├── .changeset
└── config.json
├── .github
├── FUNDING.yml
└── workflows
│ ├── ci.yml
│ └── publish.yml
├── .gitignore
├── .npmrc
├── .prettierignore
├── .prettierrc
├── .vscode
├── extensions.json
└── tasks.json
├── CHANGELOG.md
├── LICENSE
├── README.md
├── components.json
├── eslint.config.js
├── jsrepo-build-config.json
├── jsrepo.json
├── messages
├── de.json
├── en.json
└── fr.json
├── package.json
├── pnpm-lock.yaml
├── project.inlang
├── .gitignore
├── project_id
└── settings.json
├── rules
└── shadcn-svelte-extras.mdc
├── src
├── app.css
├── app.d.ts
├── app.html
├── hooks.server.ts
├── hooks.ts
├── lib
│ ├── actions
│ │ ├── active.svelte.ts
│ │ ├── shortcut.svelte.ts
│ │ └── typewriter.svelte.ts
│ ├── components
│ │ ├── app-sidebar.svelte
│ │ ├── docs
│ │ │ ├── code-span.svelte
│ │ │ ├── command
│ │ │ │ ├── command.svelte
│ │ │ │ └── index.ts
│ │ │ ├── examples
│ │ │ │ ├── code-block.svelte
│ │ │ │ ├── configure-device.svelte
│ │ │ │ ├── editor-file-tree.svelte
│ │ │ │ ├── file-drop-zone.svelte
│ │ │ │ ├── index.ts
│ │ │ │ ├── phone-number-setting.svelte
│ │ │ │ ├── pm-command.svelte
│ │ │ │ ├── review-form.svelte
│ │ │ │ └── terminal.svelte
│ │ │ ├── index.ts
│ │ │ ├── jsrepo-command.svelte
│ │ │ └── subheading.svelte
│ │ ├── icons
│ │ │ ├── css.svelte
│ │ │ ├── github.svelte
│ │ │ ├── index.ts
│ │ │ ├── mcp.svelte
│ │ │ ├── svelte.svelte
│ │ │ └── typescript.svelte
│ │ ├── installation.svelte
│ │ ├── logo.svelte
│ │ ├── page-wrapper.svelte
│ │ ├── playground.svelte
│ │ ├── search-button.svelte
│ │ ├── shadcn-svelte-extras.svelte
│ │ ├── site
│ │ │ └── meta-tags
│ │ │ │ ├── index.ts
│ │ │ │ ├── meta-tags-context.svelte.ts
│ │ │ │ └── meta-tags.svelte
│ │ └── ui
│ │ │ ├── accordion
│ │ │ ├── accordion-content.svelte
│ │ │ ├── accordion-item.svelte
│ │ │ ├── accordion-root.svelte
│ │ │ ├── accordion-trigger.svelte
│ │ │ └── index.ts
│ │ │ ├── avatar-group
│ │ │ ├── avatar-group-etc.svelte
│ │ │ ├── avatar-group-member.svelte
│ │ │ ├── avatar-group.svelte
│ │ │ └── index.ts
│ │ │ ├── avatar
│ │ │ ├── avatar-fallback.svelte
│ │ │ ├── avatar-image.svelte
│ │ │ ├── avatar.svelte
│ │ │ └── index.ts
│ │ │ ├── badge
│ │ │ ├── badge.svelte
│ │ │ └── index.ts
│ │ │ ├── button
│ │ │ ├── button.svelte
│ │ │ └── index.ts
│ │ │ ├── card
│ │ │ ├── card-action.svelte
│ │ │ ├── card-content.svelte
│ │ │ ├── card-description.svelte
│ │ │ ├── card-footer.svelte
│ │ │ ├── card-header.svelte
│ │ │ ├── card-title.svelte
│ │ │ ├── card.svelte
│ │ │ └── index.ts
│ │ │ ├── chat
│ │ │ ├── chat-bubble-avatar.svelte
│ │ │ ├── chat-bubble-message.svelte
│ │ │ ├── chat-bubble.svelte
│ │ │ ├── chat-list.svelte
│ │ │ ├── index.ts
│ │ │ └── loading-dots.svelte
│ │ │ ├── code
│ │ │ ├── code.svelte
│ │ │ ├── index.ts
│ │ │ └── shiki.ts
│ │ │ ├── collapsible
│ │ │ ├── collapsible-content.svelte
│ │ │ ├── collapsible-trigger.svelte
│ │ │ ├── collapsible.svelte
│ │ │ └── index.ts
│ │ │ ├── command
│ │ │ ├── command-dialog.svelte
│ │ │ ├── command-empty.svelte
│ │ │ ├── command-group.svelte
│ │ │ ├── command-input.svelte
│ │ │ ├── command-item.svelte
│ │ │ ├── command-link-item.svelte
│ │ │ ├── command-list.svelte
│ │ │ ├── command-separator.svelte
│ │ │ ├── command-shortcut.svelte
│ │ │ ├── command.svelte
│ │ │ └── index.ts
│ │ │ ├── copy-button
│ │ │ ├── copy-button.svelte
│ │ │ └── index.ts
│ │ │ ├── dialog
│ │ │ ├── dialog-close.svelte
│ │ │ ├── dialog-content.svelte
│ │ │ ├── dialog-description.svelte
│ │ │ ├── dialog-footer.svelte
│ │ │ ├── dialog-header.svelte
│ │ │ ├── dialog-overlay.svelte
│ │ │ ├── dialog-title.svelte
│ │ │ ├── dialog-trigger.svelte
│ │ │ └── index.ts
│ │ │ ├── drawer
│ │ │ ├── drawer-close.svelte
│ │ │ ├── drawer-content.svelte
│ │ │ ├── drawer-description.svelte
│ │ │ ├── drawer-footer.svelte
│ │ │ ├── drawer-header.svelte
│ │ │ ├── drawer-nested.svelte
│ │ │ ├── drawer-overlay.svelte
│ │ │ ├── drawer-title.svelte
│ │ │ ├── drawer-trigger.svelte
│ │ │ ├── drawer.svelte
│ │ │ └── index.ts
│ │ │ ├── dropdown-menu
│ │ │ ├── dropdown-menu-checkbox-item.svelte
│ │ │ ├── dropdown-menu-content.svelte
│ │ │ ├── dropdown-menu-group-heading.svelte
│ │ │ ├── dropdown-menu-group.svelte
│ │ │ ├── dropdown-menu-item.svelte
│ │ │ ├── dropdown-menu-label.svelte
│ │ │ ├── dropdown-menu-radio-group.svelte
│ │ │ ├── dropdown-menu-radio-item.svelte
│ │ │ ├── dropdown-menu-separator.svelte
│ │ │ ├── dropdown-menu-shortcut.svelte
│ │ │ ├── dropdown-menu-sub-content.svelte
│ │ │ ├── dropdown-menu-sub-trigger.svelte
│ │ │ ├── dropdown-menu-trigger.svelte
│ │ │ └── index.ts
│ │ │ ├── field-set
│ │ │ ├── field-set-content.svelte
│ │ │ ├── field-set-footer.svelte
│ │ │ ├── field-set-title.svelte
│ │ │ ├── field-set.svelte
│ │ │ └── index.ts
│ │ │ ├── file-drop-zone
│ │ │ ├── file-drop-zone.svelte
│ │ │ └── index.ts
│ │ │ ├── image-cropper
│ │ │ ├── image-cropper-cancel.svelte
│ │ │ ├── image-cropper-controls.svelte
│ │ │ ├── image-cropper-crop.svelte
│ │ │ ├── image-cropper-cropper.svelte
│ │ │ ├── image-cropper-dialog.svelte
│ │ │ ├── image-cropper-preview.svelte
│ │ │ ├── image-cropper-upload-trigger.svelte
│ │ │ ├── image-cropper.svelte
│ │ │ ├── image-cropper.svelte.ts
│ │ │ ├── index.ts
│ │ │ ├── types.ts
│ │ │ └── utils.ts
│ │ │ ├── input
│ │ │ ├── index.ts
│ │ │ └── input.svelte
│ │ │ ├── ipv4address-input
│ │ │ ├── index.ts
│ │ │ ├── ipv4address-input-input.svelte
│ │ │ └── ipv4address-input.svelte
│ │ │ ├── kbd
│ │ │ ├── index.ts
│ │ │ └── kbd.svelte
│ │ │ ├── label
│ │ │ ├── index.ts
│ │ │ └── label.svelte
│ │ │ ├── language-switcher
│ │ │ ├── index.ts
│ │ │ ├── language-switcher.svelte
│ │ │ └── types.ts
│ │ │ ├── light-switch
│ │ │ ├── index.ts
│ │ │ └── light-switch.svelte
│ │ │ ├── link
│ │ │ ├── index.ts
│ │ │ └── link.svelte
│ │ │ ├── modal
│ │ │ ├── index.ts
│ │ │ ├── modal-content.svelte
│ │ │ ├── modal-description.svelte
│ │ │ ├── modal-footer.svelte
│ │ │ ├── modal-header.svelte
│ │ │ ├── modal-title.svelte
│ │ │ ├── modal-trigger.svelte
│ │ │ ├── modal.svelte
│ │ │ └── modal.svelte.ts
│ │ │ ├── nlp-date-input
│ │ │ ├── index.ts
│ │ │ └── nlp-date-input.svelte
│ │ │ ├── phone-input
│ │ │ ├── country-selector.svelte
│ │ │ ├── flag.svelte
│ │ │ ├── index.ts
│ │ │ └── phone-input.svelte
│ │ │ ├── pm-command
│ │ │ ├── index.ts
│ │ │ └── pm-command.svelte
│ │ │ ├── popover
│ │ │ ├── index.ts
│ │ │ ├── popover-content.svelte
│ │ │ └── popover-trigger.svelte
│ │ │ ├── prev-next
│ │ │ ├── index.ts
│ │ │ ├── next.svelte
│ │ │ ├── prev-next.svelte
│ │ │ └── previous.svelte
│ │ │ ├── progress
│ │ │ ├── index.ts
│ │ │ └── progress.svelte
│ │ │ ├── scroll-area
│ │ │ ├── index.ts
│ │ │ ├── scroll-area-scrollbar.svelte
│ │ │ └── scroll-area.svelte
│ │ │ ├── separator
│ │ │ ├── index.ts
│ │ │ └── separator.svelte
│ │ │ ├── sheet
│ │ │ ├── index.ts
│ │ │ ├── sheet-close.svelte
│ │ │ ├── sheet-content.svelte
│ │ │ ├── sheet-description.svelte
│ │ │ ├── sheet-footer.svelte
│ │ │ ├── sheet-header.svelte
│ │ │ ├── sheet-overlay.svelte
│ │ │ ├── sheet-title.svelte
│ │ │ └── sheet-trigger.svelte
│ │ │ ├── sidebar
│ │ │ ├── constants.ts
│ │ │ ├── context.svelte.ts
│ │ │ ├── index.ts
│ │ │ ├── sidebar-content.svelte
│ │ │ ├── sidebar-footer.svelte
│ │ │ ├── sidebar-group-action.svelte
│ │ │ ├── sidebar-group-content.svelte
│ │ │ ├── sidebar-group-label.svelte
│ │ │ ├── sidebar-group.svelte
│ │ │ ├── sidebar-header.svelte
│ │ │ ├── sidebar-input.svelte
│ │ │ ├── sidebar-inset.svelte
│ │ │ ├── sidebar-menu-action.svelte
│ │ │ ├── sidebar-menu-badge.svelte
│ │ │ ├── sidebar-menu-button.svelte
│ │ │ ├── sidebar-menu-item.svelte
│ │ │ ├── sidebar-menu-skeleton.svelte
│ │ │ ├── sidebar-menu-sub-button.svelte
│ │ │ ├── sidebar-menu-sub-item.svelte
│ │ │ ├── sidebar-menu-sub.svelte
│ │ │ ├── sidebar-menu.svelte
│ │ │ ├── sidebar-provider.svelte
│ │ │ ├── sidebar-rail.svelte
│ │ │ ├── sidebar-separator.svelte
│ │ │ ├── sidebar-trigger.svelte
│ │ │ └── sidebar.svelte
│ │ │ ├── skeleton
│ │ │ ├── index.ts
│ │ │ └── skeleton.svelte
│ │ │ ├── snippet
│ │ │ ├── index.ts
│ │ │ └── snippet.svelte
│ │ │ ├── sonner
│ │ │ ├── index.ts
│ │ │ └── sonner.svelte
│ │ │ ├── star-rating
│ │ │ ├── index.ts
│ │ │ ├── star-rating-star.svelte
│ │ │ ├── star-rating.svelte
│ │ │ └── star-rating.svelte.ts
│ │ │ ├── tabs
│ │ │ ├── index.ts
│ │ │ ├── tabs-content.svelte
│ │ │ ├── tabs-list.svelte
│ │ │ ├── tabs-trigger.svelte
│ │ │ └── tabs.svelte
│ │ │ ├── tags-input
│ │ │ ├── index.ts
│ │ │ ├── tags-input-tag.svelte
│ │ │ ├── tags-input.svelte
│ │ │ └── types.ts
│ │ │ ├── terminal
│ │ │ ├── index.ts
│ │ │ ├── terminal-animated-span.svelte
│ │ │ ├── terminal-loading.svelte
│ │ │ ├── terminal-loop.svelte
│ │ │ ├── terminal-typing-animation.svelte
│ │ │ ├── terminal.svelte
│ │ │ ├── terminal.svelte.ts
│ │ │ └── types.ts
│ │ │ ├── textarea
│ │ │ ├── index.ts
│ │ │ └── textarea.svelte
│ │ │ ├── theme-selector
│ │ │ ├── index.ts
│ │ │ └── theme-selector.svelte
│ │ │ ├── toc
│ │ │ ├── index.ts
│ │ │ └── toc.svelte
│ │ │ ├── tooltip
│ │ │ ├── index.ts
│ │ │ ├── tooltip-content.svelte
│ │ │ └── tooltip-trigger.svelte
│ │ │ ├── tree-view
│ │ │ ├── index.ts
│ │ │ ├── tree-view-file.svelte
│ │ │ ├── tree-view-folder.svelte
│ │ │ └── tree-view.svelte
│ │ │ └── window
│ │ │ ├── index.ts
│ │ │ └── window.svelte
│ ├── context.ts
│ ├── hooks
│ │ ├── is-mobile.svelte.ts
│ │ ├── use-auto-scroll.svelte.ts
│ │ ├── use-boolean.svelte.ts
│ │ ├── use-clipboard.svelte.ts
│ │ ├── use-promise.svelte.ts
│ │ └── use-toc.svelte.ts
│ ├── map.ts
│ ├── utils.ts
│ └── utils
│ │ ├── box.ts
│ │ ├── ipv4-address.ts
│ │ ├── is-number.ts
│ │ ├── result.ts
│ │ ├── sleep.ts
│ │ ├── types.ts
│ │ ├── types
│ │ └── result.ts
│ │ └── utils.ts
└── routes
│ ├── +layout.svelte
│ ├── +page.svelte
│ ├── actions
│ ├── active
│ │ ├── +page.svelte
│ │ ├── basic.svelte
│ │ └── examples.ts
│ └── shortcut
│ │ ├── +page.svelte
│ │ ├── basic.svelte
│ │ └── examples.ts
│ ├── components
│ ├── +page.server.ts
│ ├── +page.svelte
│ ├── avatar-group
│ │ ├── +page.svelte
│ │ ├── basic.svelte
│ │ ├── examples.ts
│ │ └── vertical.svelte
│ ├── button
│ │ ├── +page.svelte
│ │ ├── basic.svelte
│ │ ├── examples.ts
│ │ ├── loading.svelte
│ │ └── on-click-promise.svelte
│ ├── chat
│ │ ├── +page.svelte
│ │ ├── basic.svelte
│ │ ├── data.ts
│ │ ├── examples.ts
│ │ ├── types.ts
│ │ └── utils.ts
│ ├── code
│ │ ├── +page.svelte
│ │ ├── basic.svelte
│ │ ├── examples.ts
│ │ ├── highlight-lines.svelte
│ │ ├── no-line-numbers.svelte
│ │ ├── overflow.svelte
│ │ └── variants.svelte
│ ├── copy-button
│ │ ├── +page.svelte
│ │ ├── basic.svelte
│ │ ├── examples.ts
│ │ ├── icon.svelte
│ │ └── with-text.svelte
│ ├── field-set
│ │ ├── +page.svelte
│ │ ├── basic.svelte
│ │ ├── destructive.svelte
│ │ └── examples.ts
│ ├── file-drop-zone
│ │ ├── +page.server.ts
│ │ ├── +page.svelte
│ │ ├── basic.svelte
│ │ ├── examples.ts
│ │ ├── form.svelte
│ │ └── schema.ts
│ ├── image-cropper
│ │ ├── +page.svelte
│ │ ├── basic.svelte
│ │ ├── custom-preview.svelte
│ │ ├── custom-trigger.svelte
│ │ ├── examples.ts
│ │ ├── no-default-image.svelte
│ │ └── square-preview.svelte
│ ├── ipv4address-input
│ │ ├── +page.svelte
│ │ ├── basic.svelte
│ │ ├── examples.ts
│ │ ├── placeholder.svelte
│ │ ├── reactive.svelte
│ │ └── valid.svelte
│ ├── kbd
│ │ ├── +page.svelte
│ │ ├── basic.svelte
│ │ ├── examples.ts
│ │ ├── sizes.svelte
│ │ └── variants.svelte
│ ├── language-switcher
│ │ ├── +page.svelte
│ │ ├── basic.svelte
│ │ ├── examples.ts
│ │ ├── paraglide.svelte
│ │ └── variants.svelte
│ ├── light-switch
│ │ ├── +page.svelte
│ │ ├── basic.svelte
│ │ ├── examples.ts
│ │ └── variants.svelte
│ ├── link
│ │ ├── +page.svelte
│ │ ├── basic.svelte
│ │ └── examples.ts
│ ├── modal
│ │ ├── +page.svelte
│ │ ├── basic.svelte
│ │ └── examples.ts
│ ├── nlp-date-input
│ │ ├── +page.svelte
│ │ ├── basic.svelte
│ │ ├── examples.ts
│ │ └── min-max.svelte
│ ├── phone-input
│ │ ├── +page.svelte
│ │ ├── basic.svelte
│ │ ├── custom-ordering.svelte
│ │ ├── default-country.svelte
│ │ ├── default-value.svelte
│ │ └── examples.ts
│ ├── pm-command
│ │ ├── +page.svelte
│ │ ├── basic.svelte
│ │ ├── commands.svelte
│ │ ├── customize-agents.svelte
│ │ ├── examples.ts
│ │ ├── overflow.svelte
│ │ ├── persisted-pm.svelte
│ │ └── variants.svelte
│ ├── snippet
│ │ ├── +page.svelte
│ │ ├── basic.svelte
│ │ ├── examples.ts
│ │ ├── multiline.svelte
│ │ └── variants.svelte
│ ├── star-rating
│ │ ├── +page.svelte
│ │ ├── basic.svelte
│ │ ├── custom-color.svelte
│ │ ├── custom-size.svelte
│ │ ├── custom-stars.svelte
│ │ ├── disabled.svelte
│ │ ├── examples.ts
│ │ ├── half-rating.svelte
│ │ └── readonly.svelte
│ ├── tags-input
│ │ ├── +page.svelte
│ │ ├── basic.svelte
│ │ ├── custom-validate.ts
│ │ ├── examples.ts
│ │ └── lowercase.svelte
│ ├── terminal
│ │ ├── +page.svelte
│ │ ├── basic.svelte
│ │ ├── examples.ts
│ │ └── loop.svelte
│ ├── theme-selector
│ │ ├── +page.svelte
│ │ ├── basic.svelte
│ │ ├── examples.ts
│ │ └── variants.svelte
│ ├── toc
│ │ ├── +page.svelte
│ │ ├── basic.svelte
│ │ ├── examples.ts
│ │ └── toc.ts
│ ├── tree-view
│ │ ├── +page.svelte
│ │ ├── basic.svelte
│ │ ├── custom-icons.svelte
│ │ ├── examples.ts
│ │ └── tree-view-file-custom.svelte
│ └── window
│ │ ├── +page.svelte
│ │ ├── basic.svelte
│ │ └── examples.ts
│ ├── docs
│ ├── installation
│ │ └── +page.svelte
│ ├── introduction
│ │ └── +page.svelte
│ └── using-extras
│ │ ├── +page.server.ts
│ │ └── +page.svelte
│ └── hooks
│ ├── use-auto-scroll
│ └── +page.svelte
│ ├── use-boolean
│ └── +page.svelte
│ ├── use-clipboard
│ └── +page.svelte
│ ├── use-promise
│ ├── +page.svelte
│ ├── basic.svelte
│ └── examples.ts
│ └── use-toc
│ └── +page.svelte
├── static
├── dark.svg
├── favicon.png
├── favicon.svg
├── light.svg
└── og.png
├── svelte.config.js
├── tsconfig.json
└── vite.config.ts
/.changeset/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://unpkg.com/@changesets/config@3.1.1/schema.json",
3 | "changelog": [
4 | "@svitejs/changesets-changelog-github-compact",
5 | { "repo": "ieedan/shadcn-svelte-extras" }
6 | ],
7 | "commit": false,
8 | "fixed": [],
9 | "linked": [],
10 | "access": "restricted",
11 | "baseBranch": "main",
12 | "updateInternalDependencies": "patch",
13 | "ignore": [],
14 | "privatePackages": {
15 | "version": true,
16 | "tag": true
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: [ieedan]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
12 | polar: # Replace with a single Polar username
13 | buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
14 | thanks_dev: # Replace with a single thanks.dev username
15 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
16 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on:
4 | pull_request:
5 | branches: [main]
6 |
7 | jobs:
8 | CI:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions/checkout@v4
12 | - uses: pnpm/action-setup@v4
13 | - uses: actions/setup-node@v4
14 | with:
15 | node-version: '20'
16 |
17 | - name: Install dependencies
18 | run: pnpm install
19 |
20 | - name: Generate i18n files and Lint
21 | run: pnpm generate-i18n && pnpm lint
22 |
23 | - name: Check
24 | run: pnpm check
25 |
26 | - name: Build Registry
27 | run: pnpm build:registry
28 |
--------------------------------------------------------------------------------
/.github/workflows/publish.yml:
--------------------------------------------------------------------------------
1 | name: Publish
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 |
8 | concurrency: ${{ github.workflow }}-${{ github.ref }}
9 |
10 | jobs:
11 | release:
12 | name: Build & Publish Release
13 | if: github.repository == 'ieedan/shadcn-svelte-extras'
14 | runs-on: ubuntu-latest
15 |
16 | steps:
17 | - uses: actions/checkout@v4
18 | - uses: pnpm/action-setup@v4
19 | - uses: actions/setup-node@v4
20 | with:
21 | node-version: '20'
22 | cache: pnpm
23 |
24 | - name: Install dependencies
25 | run: pnpm install
26 |
27 | - name: Kit Sync
28 | run: pnpm sync
29 |
30 | - name: Create Release Pull Request or Publish
31 | id: changesets
32 | uses: changesets/action@v1
33 | with:
34 | commit: 'chore(release): version package'
35 | title: 'chore(release): version package'
36 | publish: pnpm ci:release
37 | env:
38 | JSREPO_TOKEN: ${{ secrets.JSREPO_TOKEN }}
39 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
40 | NODE_ENV: production
41 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 |
3 | # Output
4 | .output
5 | .vercel
6 | .netlify
7 | .wrangler
8 | /.svelte-kit
9 | /build
10 |
11 | # OS
12 | .DS_Store
13 | Thumbs.db
14 |
15 | # Env
16 | .env
17 | .env.*
18 | !.env.example
19 | !.env.test
20 |
21 | # Vite
22 | vite.config.js.timestamp-*
23 | vite.config.ts.timestamp-*
24 |
25 | # Generated code
26 | src/lib/paraglide/
27 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | engine-strict=true
2 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | # Package Managers
2 | package-lock.json
3 | pnpm-lock.yaml
4 | yarn.lock
5 |
6 | CHANGELOG.md
7 |
8 | # Generated code
9 | src/lib/paraglide/
10 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "useTabs": true,
3 | "singleQuote": true,
4 | "trailingComma": "none",
5 | "printWidth": 100,
6 | "plugins": ["prettier-plugin-svelte", "prettier-plugin-tailwindcss"],
7 | "tailwindFunctions": ["tv"],
8 | "overrides": [
9 | {
10 | "files": "*.svelte",
11 | "options": {
12 | "parser": "svelte"
13 | }
14 | }
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": ["inlang.vs-code-extension"]
3 | }
4 |
--------------------------------------------------------------------------------
/components.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://next.shadcn-svelte.com/schema.json",
3 | "tailwind": {
4 | "css": "src/app.css",
5 | "baseColor": "zinc"
6 | },
7 | "aliases": {
8 | "components": "$lib/components",
9 | "utils": "$lib/utils/utils",
10 | "ui": "$lib/components/ui",
11 | "hooks": "$lib/hooks",
12 | "lib": "$lib"
13 | },
14 | "typescript": true,
15 | "registry": "https://next.shadcn-svelte.com/registry"
16 | }
17 |
--------------------------------------------------------------------------------
/jsrepo.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://unpkg.com/jsrepo@1.32.0/schemas/project-config.json",
3 | "repos": ["@ieedan/std"],
4 | "includeTests": false,
5 | "watermark": true,
6 | "formatter": "prettier",
7 | "paths": {
8 | "*": "./src/blocks",
9 | "types": "$lib/utils/types",
10 | "utils": "$lib/utils",
11 | "ui": "$lib/components/ui",
12 | "hooks": "$lib/hooks",
13 | "ts": "$lib/utils"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/messages/de.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://inlang.com/schema/inlang-message-format",
3 | "example_message": "Hallo Welt!"
4 | }
5 |
--------------------------------------------------------------------------------
/messages/en.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://inlang.com/schema/inlang-message-format",
3 | "example_message": "Hello world!"
4 | }
5 |
--------------------------------------------------------------------------------
/messages/fr.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://inlang.com/schema/inlang-message-format",
3 | "example_message": "Bonjour le monde!"
4 | }
5 |
--------------------------------------------------------------------------------
/project.inlang/.gitignore:
--------------------------------------------------------------------------------
1 | cache
--------------------------------------------------------------------------------
/project.inlang/project_id:
--------------------------------------------------------------------------------
1 | WLYo10jJ5EIfuDcXFX
--------------------------------------------------------------------------------
/project.inlang/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://inlang.com/schema/project-settings",
3 | "baseLocale": "en",
4 | "locales": ["en", "de", "fr"],
5 | "modules": [
6 | "https://cdn.jsdelivr.net/npm/@inlang/plugin-message-format@4/dist/index.js",
7 | "https://cdn.jsdelivr.net/npm/@inlang/plugin-m-function-matcher@2/dist/index.js"
8 | ],
9 | "plugin.inlang.messageFormat": {
10 | "pathPattern": "./messages/{locale}.json"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/rules/shadcn-svelte-extras.mdc:
--------------------------------------------------------------------------------
1 | ---
2 | description:
3 | globs:
4 | alwaysApply: true
5 | ---
6 | Before creating a new component try to find a component already in `@ieedan/shadcn-svelte-extras` with jsrepo. If I am using a pinned version in my [jsrepo.json](mdc:jsrepo.json) file please use that version when fetching components i.e. `@ieedan/shadcn-svelte-extras@1.0.0/ts/math`.
7 |
--------------------------------------------------------------------------------
/src/app.d.ts:
--------------------------------------------------------------------------------
1 | // See https://svelte.dev/docs/kit/types#app.d.ts
2 | // for information about these interfaces
3 | declare global {
4 | namespace App {
5 | // interface Error {}
6 | // interface Locals {}
7 | // interface PageData {}
8 | // interface PageState {}
9 | // interface Platform {}
10 | }
11 | }
12 |
13 | export {};
14 |
--------------------------------------------------------------------------------
/src/app.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | %sveltekit.head%
8 |
9 |
10 | %sveltekit.body%
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/hooks.server.ts:
--------------------------------------------------------------------------------
1 | import type { Handle } from '@sveltejs/kit';
2 | import { paraglideMiddleware } from '$lib/paraglide/server';
3 |
4 | // creating a handle to use the paraglide middleware
5 | const paraglideHandle: Handle = ({ event, resolve }) =>
6 | paraglideMiddleware(event.request, ({ request: localizedRequest, locale }) => {
7 | event.request = localizedRequest;
8 | return resolve(event, {
9 | transformPageChunk: ({ html }) => {
10 | return html.replace('%lang%', locale);
11 | }
12 | });
13 | });
14 |
15 | export const handle: Handle = paraglideHandle;
16 |
--------------------------------------------------------------------------------
/src/hooks.ts:
--------------------------------------------------------------------------------
1 | import type { Reroute } from '@sveltejs/kit';
2 | import { deLocalizeUrl } from '$lib/paraglide/runtime';
3 |
4 | export const reroute: Reroute = (request) => {
5 | return deLocalizeUrl(request.url).pathname;
6 | };
7 |
--------------------------------------------------------------------------------
/src/lib/actions/typewriter.svelte.ts:
--------------------------------------------------------------------------------
1 | import { createAttachmentKey } from 'svelte/attachments';
2 | import type { TransitionConfig } from 'svelte/transition';
3 |
4 | export type Options = {
5 | speed: number;
6 | delay: number;
7 | onComplete?: () => void;
8 | };
9 |
10 | export const typewriter = (
11 | node: HTMLElement,
12 | { speed = 1, delay = 0, onComplete }: Partial
13 | ) => {
14 | const text = node.textContent ?? '';
15 | const duration = text.length / (speed * 0.01);
16 |
17 | return {
18 | delay,
19 | duration,
20 | tick: (t) => {
21 | const i = Math.trunc(text.length * t);
22 | node.textContent = text.slice(0, i);
23 | if (node.textContent.length === text.length) onComplete?.();
24 | }
25 | } satisfies TransitionConfig;
26 | };
27 |
28 | export function attachTypewriter(opts: Partial = {}) {
29 | return {
30 | [createAttachmentKey()]: (node: HTMLElement) => typewriter(node, opts)
31 | };
32 | }
33 |
--------------------------------------------------------------------------------
/src/lib/components/docs/code-span.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 | {@render children?.()}
14 |
15 |
--------------------------------------------------------------------------------
/src/lib/components/docs/command/index.ts:
--------------------------------------------------------------------------------
1 | import Command from './command.svelte';
2 |
3 | export { Command };
4 |
--------------------------------------------------------------------------------
/src/lib/components/docs/examples/code-block.svelte:
--------------------------------------------------------------------------------
1 |
9 |
10 | `;
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | src/routes/+layout.svelte
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/lib/components/docs/examples/index.ts:
--------------------------------------------------------------------------------
1 | import ReviewForm from './review-form.svelte';
2 | import ConfigureDevice from './configure-device.svelte';
3 | import PhoneNumberSetting from './phone-number-setting.svelte';
4 | import CodeBlock from './code-block.svelte';
5 | import EditorFileTree from './editor-file-tree.svelte';
6 | import Terminal from './terminal.svelte';
7 | import FileDropZone from './file-drop-zone.svelte';
8 | import PmCommand from './pm-command.svelte';
9 |
10 | export {
11 | ReviewForm,
12 | PmCommand,
13 | ConfigureDevice,
14 | PhoneNumberSetting,
15 | CodeBlock,
16 | EditorFileTree,
17 | Terminal,
18 | FileDropZone
19 | };
20 |
--------------------------------------------------------------------------------
/src/lib/components/docs/examples/phone-number-setting.svelte:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 | Phone Number
12 |
13 |
14 |
15 | Add your phone number.
16 | {
20 | loading = true;
21 | setTimeout(() => {
22 | loading = false;
23 | }, 500);
24 | }}
25 | >
26 | Save
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/src/lib/components/docs/examples/pm-command.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/lib/components/docs/index.ts:
--------------------------------------------------------------------------------
1 | import Subheading from './subheading.svelte';
2 | import CodeSpan from './code-span.svelte';
3 |
4 | export { Subheading, CodeSpan };
5 |
--------------------------------------------------------------------------------
/src/lib/components/docs/subheading.svelte:
--------------------------------------------------------------------------------
1 |
19 |
20 |
26 | {@render children?.()}
27 |
28 |
--------------------------------------------------------------------------------
/src/lib/components/icons/index.ts:
--------------------------------------------------------------------------------
1 | import type { HTMLAttributes } from 'svelte/elements';
2 | import GitHub from './github.svelte';
3 | import Svelte from './svelte.svelte';
4 | import CSS from './css.svelte';
5 | import MCP from './mcp.svelte';
6 | import TypeScript from './typescript.svelte';
7 |
8 | export interface Props extends HTMLAttributes {
9 | class?: string;
10 | width?: number;
11 | height?: number;
12 | }
13 |
14 | export { GitHub, Svelte, CSS, TypeScript, MCP };
15 |
--------------------------------------------------------------------------------
/src/lib/components/installation.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 | Installation
13 |
14 |
--------------------------------------------------------------------------------
/src/lib/components/search-button.svelte:
--------------------------------------------------------------------------------
1 |
16 |
17 |
22 |
23 |
24 | Search
25 |
26 |
27 |
28 | + K
29 |
30 |
31 |
--------------------------------------------------------------------------------
/src/lib/components/shadcn-svelte-extras.svelte:
--------------------------------------------------------------------------------
1 | shadcn-svelte-extras
2 |
--------------------------------------------------------------------------------
/src/lib/components/site/meta-tags/index.ts:
--------------------------------------------------------------------------------
1 | export { default as MetaTags } from './meta-tags.svelte';
2 |
--------------------------------------------------------------------------------
/src/lib/components/site/meta-tags/meta-tags-context.svelte.ts:
--------------------------------------------------------------------------------
1 | import { Context } from 'runed';
2 | import type { ReadableBoxedValues } from 'svelte-toolbelt';
3 | import { deepMerge, type MetaTagsProps } from 'svelte-meta-tags';
4 |
5 | export type RootStateProps = ReadableBoxedValues<{
6 | props: Partial;
7 | }>;
8 |
9 | export class MetaTagsRootState {
10 | constructor(
11 | readonly base: MetaTagsRootState | null,
12 | readonly opts: RootStateProps
13 | ) {
14 | if (this.base === null) {
15 | ctx.set(this);
16 | }
17 | }
18 |
19 | get props() {
20 | const baseProps: Partial = this.base ? this.base.props : {};
21 |
22 | return deepMerge(baseProps, this.opts.props.current);
23 | }
24 | }
25 |
26 | const ctx = new Context('meta-tags-ctx');
27 |
28 | export function useMetaTags(opts: RootStateProps) {
29 | let base: MetaTagsRootState | null;
30 | try {
31 | base = ctx.get();
32 | } catch {
33 | base = null;
34 | }
35 |
36 | return new MetaTagsRootState(base, opts);
37 | }
38 |
--------------------------------------------------------------------------------
/src/lib/components/site/meta-tags/meta-tags.svelte:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/lib/components/ui/accordion/accordion-content.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
22 |
23 | {@render children?.()}
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/lib/components/ui/accordion/accordion-item.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 |
18 |
--------------------------------------------------------------------------------
/src/lib/components/ui/accordion/accordion-root.svelte:
--------------------------------------------------------------------------------
1 |
10 |
11 |
17 |
--------------------------------------------------------------------------------
/src/lib/components/ui/accordion/index.ts:
--------------------------------------------------------------------------------
1 | import Root from './accordion-root.svelte';
2 | import Content from './accordion-content.svelte';
3 | import Item from './accordion-item.svelte';
4 | import Trigger from './accordion-trigger.svelte';
5 |
6 | export {
7 | Root,
8 | Content,
9 | Item,
10 | Trigger,
11 | //
12 | Root as Accordion,
13 | Content as AccordionContent,
14 | Item as AccordionItem,
15 | Trigger as AccordionTrigger
16 | };
17 |
--------------------------------------------------------------------------------
/src/lib/components/ui/avatar-group/avatar-group-etc.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 |
18 | +{plus}
19 |
20 |
--------------------------------------------------------------------------------
/src/lib/components/ui/avatar-group/avatar-group-member.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/lib/components/ui/avatar-group/avatar-group.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
20 | {@render children?.()}
21 |
22 |
--------------------------------------------------------------------------------
/src/lib/components/ui/avatar-group/index.ts:
--------------------------------------------------------------------------------
1 | import Root from './avatar-group.svelte';
2 | import Member from './avatar-group-member.svelte';
3 | import Etc from './avatar-group-etc.svelte';
4 |
5 | import { Fallback, Image } from '$lib/components/ui/avatar';
6 |
7 | export { Root, Member, Etc, Image as MemberImage, Fallback as MemberFallback };
8 |
--------------------------------------------------------------------------------
/src/lib/components/ui/avatar/avatar-fallback.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 |
18 |
--------------------------------------------------------------------------------
/src/lib/components/ui/avatar/avatar-image.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 |
18 |
--------------------------------------------------------------------------------
/src/lib/components/ui/avatar/avatar.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 |
18 |
--------------------------------------------------------------------------------
/src/lib/components/ui/avatar/index.ts:
--------------------------------------------------------------------------------
1 | import Root from './avatar.svelte';
2 | import Image from './avatar-image.svelte';
3 | import Fallback from './avatar-fallback.svelte';
4 |
5 | export {
6 | Root,
7 | Image,
8 | Fallback,
9 | //
10 | Root as Avatar,
11 | Image as AvatarImage,
12 | Fallback as AvatarFallback
13 | };
14 |
--------------------------------------------------------------------------------
/src/lib/components/ui/badge/index.ts:
--------------------------------------------------------------------------------
1 | export { default as Badge } from './badge.svelte';
2 | export { badgeVariants, type BadgeVariant } from './badge.svelte';
3 |
--------------------------------------------------------------------------------
/src/lib/components/ui/button/index.ts:
--------------------------------------------------------------------------------
1 | import Root, {
2 | type ButtonProps,
3 | type ButtonSize,
4 | type ButtonVariant,
5 | buttonVariants
6 | } from './button.svelte';
7 |
8 | export {
9 | Root,
10 | type ButtonProps as Props,
11 | //
12 | Root as Button,
13 | buttonVariants,
14 | type ButtonProps,
15 | type ButtonSize,
16 | type ButtonVariant
17 | };
18 |
--------------------------------------------------------------------------------
/src/lib/components/ui/card/card-action.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
19 | {@render children?.()}
20 |
21 |
--------------------------------------------------------------------------------
/src/lib/components/ui/card/card-content.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
14 | {@render children?.()}
15 |
16 |
--------------------------------------------------------------------------------
/src/lib/components/ui/card/card-description.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
19 | {@render children?.()}
20 |
21 |
--------------------------------------------------------------------------------
/src/lib/components/ui/card/card-footer.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
19 | {@render children?.()}
20 |
21 |
--------------------------------------------------------------------------------
/src/lib/components/ui/card/card-header.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
22 | {@render children?.()}
23 |
24 |
--------------------------------------------------------------------------------
/src/lib/components/ui/card/card-title.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
19 | {@render children?.()}
20 |
21 |
--------------------------------------------------------------------------------
/src/lib/components/ui/card/card.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
22 | {@render children?.()}
23 |
24 |
--------------------------------------------------------------------------------
/src/lib/components/ui/card/index.ts:
--------------------------------------------------------------------------------
1 | import Root from './card.svelte';
2 | import Content from './card-content.svelte';
3 | import Description from './card-description.svelte';
4 | import Footer from './card-footer.svelte';
5 | import Header from './card-header.svelte';
6 | import Title from './card-title.svelte';
7 | import Action from './card-action.svelte';
8 |
9 | export {
10 | Root,
11 | Content,
12 | Description,
13 | Footer,
14 | Header,
15 | Title,
16 | Action,
17 | //
18 | Root as Card,
19 | Content as CardContent,
20 | Description as CardDescription,
21 | Footer as CardFooter,
22 | Header as CardHeader,
23 | Title as CardTitle,
24 | Action as CardAction
25 | };
26 |
--------------------------------------------------------------------------------
/src/lib/components/ui/chat/chat-bubble-avatar.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
18 |
--------------------------------------------------------------------------------
/src/lib/components/ui/chat/chat-bubble-message.svelte:
--------------------------------------------------------------------------------
1 |
14 |
15 |
21 | {#if typing}
22 |
23 |
24 |
25 | {:else}
26 | {@render children?.()}
27 | {/if}
28 |
29 |
--------------------------------------------------------------------------------
/src/lib/components/ui/chat/chat-bubble.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 |
16 | {@render children?.()}
17 |
18 |
--------------------------------------------------------------------------------
/src/lib/components/ui/chat/index.ts:
--------------------------------------------------------------------------------
1 | import Bubble from './chat-bubble.svelte';
2 | import BubbleMessage from './chat-bubble-message.svelte';
3 | import BubbleAvatar from './chat-bubble-avatar.svelte';
4 | import List from './chat-list.svelte';
5 | import * as Avatar from '$lib/components/ui/avatar';
6 |
7 | const BubbleAvatarImage = Avatar.Image;
8 | const BubbleAvatarFallback = Avatar.Fallback;
9 |
10 | export { List, Bubble, BubbleMessage, BubbleAvatar, BubbleAvatarImage, BubbleAvatarFallback };
11 |
--------------------------------------------------------------------------------
/src/lib/components/ui/chat/loading-dots.svelte:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 | {#each { length: 3 } as _, i (i)}
11 |
12 | {/each}
13 |
14 |
15 |
43 |
--------------------------------------------------------------------------------
/src/lib/components/ui/code/index.ts:
--------------------------------------------------------------------------------
1 | import Code from './code.svelte';
2 |
3 | export { Code };
4 |
--------------------------------------------------------------------------------
/src/lib/components/ui/code/shiki.ts:
--------------------------------------------------------------------------------
1 | // Follows the best practices established in https://shiki.matsu.io/guide/best-performance
2 | import { createJavaScriptRegexEngine } from 'shiki/engine/javascript';
3 | import { createHighlighterCore } from 'shiki/core';
4 |
5 | const bundledLanguages = {
6 | bash: () => import('@shikijs/langs/bash'),
7 | diff: () => import('@shikijs/langs/diff'),
8 | javascript: () => import('@shikijs/langs/javascript'),
9 | json: () => import('@shikijs/langs/json'),
10 | svelte: () => import('@shikijs/langs/svelte'),
11 | typescript: () => import('@shikijs/langs/typescript')
12 | };
13 |
14 | /** The languages configured for the highlighter */
15 | export type SupportedLanguage = keyof typeof bundledLanguages;
16 |
17 | /** A preloaded highlighter instance. */
18 | export const highlighter = createHighlighterCore({
19 | themes: [
20 | import('@shikijs/themes/github-light-default'),
21 | import('@shikijs/themes/github-dark-default')
22 | ],
23 | langs: Object.entries(bundledLanguages).map(([_, lang]) => lang),
24 | engine: createJavaScriptRegexEngine()
25 | });
26 |
--------------------------------------------------------------------------------
/src/lib/components/ui/collapsible/collapsible-content.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/lib/components/ui/collapsible/collapsible-trigger.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/lib/components/ui/collapsible/collapsible.svelte:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/lib/components/ui/collapsible/index.ts:
--------------------------------------------------------------------------------
1 | import { Collapsible as CollapsiblePrimitive } from 'bits-ui';
2 |
3 | const Root = CollapsiblePrimitive.Root;
4 | const Trigger = CollapsiblePrimitive.Trigger;
5 | const Content = CollapsiblePrimitive.Content;
6 |
7 | export {
8 | Root,
9 | Content,
10 | Trigger,
11 | //
12 | Root as Collapsible,
13 | Content as CollapsibleContent,
14 | Trigger as CollapsibleTrigger
15 | };
16 |
--------------------------------------------------------------------------------
/src/lib/components/ui/command/command-empty.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 |
18 |
--------------------------------------------------------------------------------
/src/lib/components/ui/command/command-group.svelte:
--------------------------------------------------------------------------------
1 |
16 |
17 |
24 | {#if heading}
25 |
26 | {heading}
27 |
28 | {/if}
29 |
30 |
31 |
--------------------------------------------------------------------------------
/src/lib/components/ui/command/command-input.svelte:
--------------------------------------------------------------------------------
1 |
13 |
14 |
15 |
16 |
26 |
27 |
--------------------------------------------------------------------------------
/src/lib/components/ui/command/command-item.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 |
21 |
--------------------------------------------------------------------------------
/src/lib/components/ui/command/command-link-item.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 |
21 |
--------------------------------------------------------------------------------
/src/lib/components/ui/command/command-list.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 |
18 |
--------------------------------------------------------------------------------
/src/lib/components/ui/command/command-separator.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 |
18 |
--------------------------------------------------------------------------------
/src/lib/components/ui/command/command-shortcut.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
19 | {@render children?.()}
20 |
21 |
--------------------------------------------------------------------------------
/src/lib/components/ui/command/command.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
23 |
--------------------------------------------------------------------------------
/src/lib/components/ui/copy-button/index.ts:
--------------------------------------------------------------------------------
1 | import CopyButton from './copy-button.svelte';
2 |
3 | export { CopyButton };
4 |
--------------------------------------------------------------------------------
/src/lib/components/ui/dialog/dialog-close.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/lib/components/ui/dialog/dialog-description.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 |
18 |
--------------------------------------------------------------------------------
/src/lib/components/ui/dialog/dialog-footer.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
19 | {@render children?.()}
20 |
21 |
--------------------------------------------------------------------------------
/src/lib/components/ui/dialog/dialog-header.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
19 | {@render children?.()}
20 |
21 |
--------------------------------------------------------------------------------
/src/lib/components/ui/dialog/dialog-overlay.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 |
21 |
--------------------------------------------------------------------------------
/src/lib/components/ui/dialog/dialog-title.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 |
18 |
--------------------------------------------------------------------------------
/src/lib/components/ui/dialog/dialog-trigger.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/lib/components/ui/dialog/index.ts:
--------------------------------------------------------------------------------
1 | import { Dialog as DialogPrimitive } from 'bits-ui';
2 |
3 | import Title from './dialog-title.svelte';
4 | import Footer from './dialog-footer.svelte';
5 | import Header from './dialog-header.svelte';
6 | import Overlay from './dialog-overlay.svelte';
7 | import Content from './dialog-content.svelte';
8 | import Description from './dialog-description.svelte';
9 | import Trigger from './dialog-trigger.svelte';
10 | import Close from './dialog-close.svelte';
11 |
12 | const Root = DialogPrimitive.Root;
13 | const Portal = DialogPrimitive.Portal;
14 |
15 | export {
16 | Root,
17 | Title,
18 | Portal,
19 | Footer,
20 | Header,
21 | Trigger,
22 | Overlay,
23 | Content,
24 | Description,
25 | Close,
26 | //
27 | Root as Dialog,
28 | Title as DialogTitle,
29 | Portal as DialogPortal,
30 | Footer as DialogFooter,
31 | Header as DialogHeader,
32 | Trigger as DialogTrigger,
33 | Overlay as DialogOverlay,
34 | Content as DialogContent,
35 | Description as DialogDescription,
36 | Close as DialogClose
37 | };
38 |
--------------------------------------------------------------------------------
/src/lib/components/ui/drawer/drawer-close.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/lib/components/ui/drawer/drawer-description.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 |
18 |
--------------------------------------------------------------------------------
/src/lib/components/ui/drawer/drawer-footer.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
19 | {@render children?.()}
20 |
21 |
--------------------------------------------------------------------------------
/src/lib/components/ui/drawer/drawer-header.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
19 | {@render children?.()}
20 |
21 |
--------------------------------------------------------------------------------
/src/lib/components/ui/drawer/drawer-nested.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/lib/components/ui/drawer/drawer-overlay.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 |
21 |
--------------------------------------------------------------------------------
/src/lib/components/ui/drawer/drawer-title.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 |
18 |
--------------------------------------------------------------------------------
/src/lib/components/ui/drawer/drawer-trigger.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/lib/components/ui/drawer/drawer.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte:
--------------------------------------------------------------------------------
1 |
15 |
16 |
23 |
--------------------------------------------------------------------------------
/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte:
--------------------------------------------------------------------------------
1 |
15 |
16 |
23 | {@render children?.()}
24 |
25 |
--------------------------------------------------------------------------------
/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte:
--------------------------------------------------------------------------------
1 |
10 |
11 |
17 |
--------------------------------------------------------------------------------
/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 |
18 |
--------------------------------------------------------------------------------
/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
19 | {@render children?.()}
20 |
21 |
--------------------------------------------------------------------------------
/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 |
21 |
--------------------------------------------------------------------------------
/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/lib/components/ui/field-set/field-set-content.svelte:
--------------------------------------------------------------------------------
1 |
17 |
18 |
19 | {@render children?.()}
20 |
21 |
--------------------------------------------------------------------------------
/src/lib/components/ui/field-set/field-set-footer.svelte:
--------------------------------------------------------------------------------
1 |
17 |
18 |
19 | {@render children?.()}
20 |
21 |
--------------------------------------------------------------------------------
/src/lib/components/ui/field-set/field-set-title.svelte:
--------------------------------------------------------------------------------
1 |
16 |
17 |
24 | {@render children?.()}
25 |
26 |
--------------------------------------------------------------------------------
/src/lib/components/ui/field-set/field-set.svelte:
--------------------------------------------------------------------------------
1 |
25 |
26 |
27 | {@render children?.()}
28 |
29 |
--------------------------------------------------------------------------------
/src/lib/components/ui/field-set/index.ts:
--------------------------------------------------------------------------------
1 | import Root from './field-set.svelte';
2 | import Content from './field-set-content.svelte';
3 | import Footer from './field-set-footer.svelte';
4 | import Title from './field-set-title.svelte';
5 |
6 | export { Root, Content, Footer, Title };
7 |
--------------------------------------------------------------------------------
/src/lib/components/ui/file-drop-zone/index.ts:
--------------------------------------------------------------------------------
1 | import FileDropZone, {
2 | type FileRejectedReason,
3 | type FileDropZoneProps
4 | } from './file-drop-zone.svelte';
5 |
6 | export const displaySize = (bytes: number): string => {
7 | if (bytes < KILOBYTE) return `${bytes.toFixed(0)} B`;
8 |
9 | if (bytes < MEGABYTE) return `${(bytes / KILOBYTE).toFixed(0)} KB`;
10 |
11 | if (bytes < GIGABYTE) return `${(bytes / MEGABYTE).toFixed(0)} MB`;
12 |
13 | return `${(bytes / GIGABYTE).toFixed(0)} GB`;
14 | };
15 |
16 | // Utilities for working with file sizes
17 | export const BYTE = 1;
18 | export const KILOBYTE = 1024;
19 | export const MEGABYTE = 1024 * KILOBYTE;
20 | export const GIGABYTE = 1024 * MEGABYTE;
21 |
22 | // utilities for limiting accepted files
23 | export const ACCEPT_IMAGE = 'image/*';
24 | export const ACCEPT_VIDEO = 'video/*';
25 | export const ACCEPT_AUDIO = 'audio/*';
26 |
27 | export { FileDropZone, type FileRejectedReason, type FileDropZoneProps };
28 |
--------------------------------------------------------------------------------
/src/lib/components/ui/image-cropper/image-cropper-cancel.svelte:
--------------------------------------------------------------------------------
1 |
15 |
16 |
17 |
18 | Cancel
19 |
20 |
--------------------------------------------------------------------------------
/src/lib/components/ui/image-cropper/image-cropper-controls.svelte:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 | {@render children?.()}
10 |
11 |
--------------------------------------------------------------------------------
/src/lib/components/ui/image-cropper/image-cropper-crop.svelte:
--------------------------------------------------------------------------------
1 |
15 |
16 |
17 |
18 | Crop
19 |
20 |
--------------------------------------------------------------------------------
/src/lib/components/ui/image-cropper/image-cropper-cropper.svelte:
--------------------------------------------------------------------------------
1 |
14 |
15 |
16 |
17 |
25 |
26 |
--------------------------------------------------------------------------------
/src/lib/components/ui/image-cropper/image-cropper-dialog.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
21 |
22 | {@render children?.()}
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/lib/components/ui/image-cropper/image-cropper-preview.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 | {#if child}
14 | {@render child({ src: previewState.rootState.src })}
15 | {:else}
16 |
19 |
20 |
21 |
22 | Upload image
23 |
24 |
25 | {/if}
26 |
--------------------------------------------------------------------------------
/src/lib/components/ui/image-cropper/image-cropper-upload-trigger.svelte:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 | {@render children?.()}
12 |
13 |
--------------------------------------------------------------------------------
/src/lib/components/ui/image-cropper/image-cropper.svelte:
--------------------------------------------------------------------------------
1 |
27 |
28 | {@render children?.()}
29 | {
32 | const file = e.currentTarget.files?.[0];
33 | if (!file) return;
34 | rootState.onUpload(file);
35 | // reset so that we can reupload the same file
36 | (e.target! as HTMLInputElement).value = '';
37 | }}
38 | type="file"
39 | {id}
40 | style="display: none;"
41 | />
42 |
--------------------------------------------------------------------------------
/src/lib/components/ui/image-cropper/index.ts:
--------------------------------------------------------------------------------
1 | import Root from './image-cropper.svelte';
2 | import UploadTrigger from './image-cropper-upload-trigger.svelte';
3 | import Preview from './image-cropper-preview.svelte';
4 | import Dialog from './image-cropper-dialog.svelte';
5 | import Cropper from './image-cropper-cropper.svelte';
6 | import Controls from './image-cropper-controls.svelte';
7 | import Crop from './image-cropper-crop.svelte';
8 | import Cancel from './image-cropper-cancel.svelte';
9 | import { getFileFromUrl } from './utils';
10 |
11 | export { Root, UploadTrigger, Preview, Dialog, Cropper, Controls, Crop, Cancel, getFileFromUrl };
12 |
--------------------------------------------------------------------------------
/src/lib/components/ui/image-cropper/types.ts:
--------------------------------------------------------------------------------
1 | import type { AvatarRootProps, DialogContentProps, WithChildren } from 'bits-ui';
2 | import type { Snippet } from 'svelte';
3 | import type { HTMLInputAttributes } from 'svelte/elements';
4 |
5 | export type ImageCropperRootProps = HTMLInputAttributes &
6 | WithChildren<{
7 | id?: string;
8 | src?: string;
9 | onCropped?: (url: string) => void;
10 | }>;
11 |
12 | export type ImageCropperDialogProps = DialogContentProps;
13 |
14 | export type ImageCropperPreviewProps = Omit & {
15 | child?: Snippet<[{ src: string }]>;
16 | };
17 |
--------------------------------------------------------------------------------
/src/lib/components/ui/input/index.ts:
--------------------------------------------------------------------------------
1 | import Root from './input.svelte';
2 |
3 | export {
4 | Root,
5 | //
6 | Root as Input
7 | };
8 |
--------------------------------------------------------------------------------
/src/lib/components/ui/kbd/index.ts:
--------------------------------------------------------------------------------
1 | import Kbd from './kbd.svelte';
2 |
3 | export { Kbd };
4 |
--------------------------------------------------------------------------------
/src/lib/components/ui/label/index.ts:
--------------------------------------------------------------------------------
1 | import Root from './label.svelte';
2 |
3 | export {
4 | Root,
5 | //
6 | Root as Label
7 | };
8 |
--------------------------------------------------------------------------------
/src/lib/components/ui/label/label.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 |
20 |
--------------------------------------------------------------------------------
/src/lib/components/ui/language-switcher/index.ts:
--------------------------------------------------------------------------------
1 | import LanguageSwitcher from './language-switcher.svelte';
2 |
3 | export type * from './types';
4 |
5 | export { LanguageSwitcher as Root, LanguageSwitcher };
6 |
--------------------------------------------------------------------------------
/src/lib/components/ui/language-switcher/types.ts:
--------------------------------------------------------------------------------
1 | export interface Language {
2 | /** Language code (e.g., 'en', 'de') */
3 | code: string;
4 | /** Display name (e.g., 'English', 'Deutsch') */
5 | label: string;
6 | }
7 |
8 | export interface LanguageSwitcherProps {
9 | /** List of available languages */
10 | languages: Language[];
11 |
12 | /** Current selected language code */
13 | value?: string;
14 |
15 | /** Dropdown alignment */
16 | align?: 'start' | 'center' | 'end';
17 |
18 | /** Button variant */
19 | variant?: 'outline' | 'ghost';
20 |
21 | /** Called when the language changes */
22 | onChange?: (code: string) => void;
23 |
24 | class?: string;
25 | }
26 |
--------------------------------------------------------------------------------
/src/lib/components/ui/light-switch/index.ts:
--------------------------------------------------------------------------------
1 | import LightSwitch from './light-switch.svelte';
2 |
3 | export { LightSwitch };
4 |
--------------------------------------------------------------------------------
/src/lib/components/ui/light-switch/light-switch.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
14 |
15 |
16 | Toggle theme
17 |
18 |
--------------------------------------------------------------------------------
/src/lib/components/ui/link/index.ts:
--------------------------------------------------------------------------------
1 | import Link from './link.svelte';
2 |
3 | export { Link };
4 |
--------------------------------------------------------------------------------
/src/lib/components/ui/link/link.svelte:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 | {@render children?.()}
10 |
11 |
--------------------------------------------------------------------------------
/src/lib/components/ui/modal/index.ts:
--------------------------------------------------------------------------------
1 | import Root from './modal.svelte';
2 | import Trigger from './modal-trigger.svelte';
3 | import Content from './modal-content.svelte';
4 | import Footer from './modal-footer.svelte';
5 | import Header from './modal-header.svelte';
6 | import Title from './modal-title.svelte';
7 | import Description from './modal-description.svelte';
8 |
9 | export { Root, Trigger, Content, Footer, Header, Title, Description };
10 |
--------------------------------------------------------------------------------
/src/lib/components/ui/modal/modal-content.svelte:
--------------------------------------------------------------------------------
1 |
16 |
17 | {#if modal.view === 'desktop'}
18 |
19 | {@render children?.()}
20 |
21 | {:else}
22 |
23 | {@render children?.()}
24 |
25 | {/if}
26 |
--------------------------------------------------------------------------------
/src/lib/components/ui/modal/modal-description.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 | {#if modal.view === 'desktop'}
13 |
14 | {:else}
15 |
16 | {/if}
17 |
--------------------------------------------------------------------------------
/src/lib/components/ui/modal/modal-footer.svelte:
--------------------------------------------------------------------------------
1 |
16 |
17 | {#if modal.view === 'desktop'}
18 |
19 | {@render children?.()}
20 |
21 | {:else}
22 |
23 | {@render children?.()}
24 |
25 | {/if}
26 |
--------------------------------------------------------------------------------
/src/lib/components/ui/modal/modal-header.svelte:
--------------------------------------------------------------------------------
1 |
16 |
17 | {#if modal.view === 'desktop'}
18 |
19 | {@render children?.()}
20 |
21 | {:else}
22 |
23 | {@render children?.()}
24 |
25 | {/if}
26 |
--------------------------------------------------------------------------------
/src/lib/components/ui/modal/modal-title.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 | {#if modal.view === 'desktop'}
13 |
14 | {:else}
15 |
16 | {/if}
17 |
--------------------------------------------------------------------------------
/src/lib/components/ui/modal/modal-trigger.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 | {#if modal.view === 'desktop'}
13 |
14 | {@render children?.()}
15 |
16 | {:else}
17 |
18 | {@render children?.()}
19 |
20 | {/if}
21 |
--------------------------------------------------------------------------------
/src/lib/components/ui/modal/modal.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 | {#if modal.view === 'desktop'}
13 |
14 | {@render children?.()}
15 |
16 | {:else}
17 |
18 | {@render children?.()}
19 |
20 | {/if}
21 |
--------------------------------------------------------------------------------
/src/lib/components/ui/modal/modal.svelte.ts:
--------------------------------------------------------------------------------
1 | import { Context } from 'runed';
2 | import { MediaQuery } from 'svelte/reactivity';
3 |
4 | class ModalRootState {
5 | #isDesktop = new MediaQuery('(min-width: 768px)');
6 |
7 | get view() {
8 | return this.#isDesktop.current ? 'desktop' : 'mobile';
9 | }
10 | }
11 |
12 | class ModalSubState {
13 | constructor(private root: ModalRootState) {}
14 |
15 | get view() {
16 | return this.root.view;
17 | }
18 | }
19 |
20 | const ctx = new Context('modal-root-state');
21 |
22 | export function useModal() {
23 | return ctx.set(new ModalRootState());
24 | }
25 |
26 | export function useModalSub() {
27 | return new ModalSubState(ctx.get());
28 | }
29 |
--------------------------------------------------------------------------------
/src/lib/components/ui/nlp-date-input/index.ts:
--------------------------------------------------------------------------------
1 | import NLPDateInput from './nlp-date-input.svelte';
2 |
3 | export { NLPDateInput };
4 |
--------------------------------------------------------------------------------
/src/lib/components/ui/phone-input/flag.svelte:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 | {#if country}
13 |
17 | {/if}
18 |
19 |
--------------------------------------------------------------------------------
/src/lib/components/ui/phone-input/index.ts:
--------------------------------------------------------------------------------
1 | import PhoneInput from './phone-input.svelte';
2 | import type {
3 | Country,
4 | CountryCode,
5 | DetailedValue,
6 | E164Number,
7 | TelInputOptions
8 | } from 'svelte-tel-input/types';
9 |
10 | export type Props = {
11 | country?: CountryCode | null;
12 | defaultCountry?: CountryCode | null;
13 | el?: HTMLInputElement;
14 | name?: string;
15 | placeholder?: string;
16 | disabled?: boolean;
17 | readonly?: boolean;
18 | class?: string;
19 | value?: E164Number | null;
20 | valid?: boolean;
21 | detailedValue?: Partial | null;
22 | options?: TelInputOptions;
23 | order?: ((a: Country, b: Country) => number) | undefined;
24 | };
25 |
26 | export const defaultOptions: TelInputOptions = {
27 | spaces: true,
28 | autoPlaceholder: false,
29 | format: 'international'
30 | };
31 |
32 | export { PhoneInput };
33 |
--------------------------------------------------------------------------------
/src/lib/components/ui/pm-command/index.ts:
--------------------------------------------------------------------------------
1 | import PMCommand from './pm-command.svelte';
2 |
3 | export { PMCommand };
4 |
--------------------------------------------------------------------------------
/src/lib/components/ui/popover/index.ts:
--------------------------------------------------------------------------------
1 | import { Popover as PopoverPrimitive } from 'bits-ui';
2 | import Content from './popover-content.svelte';
3 | import Trigger from './popover-trigger.svelte';
4 | const Root = PopoverPrimitive.Root;
5 | const Close = PopoverPrimitive.Close;
6 |
7 | export {
8 | Root,
9 | Content,
10 | Trigger,
11 | Close,
12 | //
13 | Root as Popover,
14 | Content as PopoverContent,
15 | Trigger as PopoverTrigger,
16 | Close as PopoverClose
17 | };
18 |
--------------------------------------------------------------------------------
/src/lib/components/ui/popover/popover-trigger.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 |
18 |
--------------------------------------------------------------------------------
/src/lib/components/ui/prev-next/index.ts:
--------------------------------------------------------------------------------
1 | import Root from './prev-next.svelte';
2 | import Next from './next.svelte';
3 | import Previous from './previous.svelte';
4 |
5 | export { Root, Next, Previous };
6 |
--------------------------------------------------------------------------------
/src/lib/components/ui/prev-next/next.svelte:
--------------------------------------------------------------------------------
1 |
13 |
14 |
20 | {@render children()}
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/lib/components/ui/prev-next/prev-next.svelte:
--------------------------------------------------------------------------------
1 |
13 |
14 |
15 |
16 | {@render previous?.()}
17 |
18 |
19 | {@render next?.()}
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/lib/components/ui/prev-next/previous.svelte:
--------------------------------------------------------------------------------
1 |
13 |
14 |
20 |
21 | {@render children()}
22 |
23 |
--------------------------------------------------------------------------------
/src/lib/components/ui/progress/index.ts:
--------------------------------------------------------------------------------
1 | import Root from './progress.svelte';
2 |
3 | export {
4 | Root,
5 | //
6 | Root as Progress
7 | };
8 |
--------------------------------------------------------------------------------
/src/lib/components/ui/progress/progress.svelte:
--------------------------------------------------------------------------------
1 |
13 |
14 |
22 |
27 |
28 |
--------------------------------------------------------------------------------
/src/lib/components/ui/scroll-area/index.ts:
--------------------------------------------------------------------------------
1 | import Scrollbar from './scroll-area-scrollbar.svelte';
2 | import Root from './scroll-area.svelte';
3 |
4 | export {
5 | Root,
6 | Scrollbar,
7 | //,
8 | Root as ScrollArea,
9 | Scrollbar as ScrollAreaScrollbar
10 | };
11 |
--------------------------------------------------------------------------------
/src/lib/components/ui/scroll-area/scroll-area-scrollbar.svelte:
--------------------------------------------------------------------------------
1 |
13 |
14 |
26 | {@render children?.()}
27 |
31 |
32 |
--------------------------------------------------------------------------------
/src/lib/components/ui/separator/index.ts:
--------------------------------------------------------------------------------
1 | import Root from './separator.svelte';
2 |
3 | export {
4 | Root,
5 | //
6 | Root as Separator
7 | };
8 |
--------------------------------------------------------------------------------
/src/lib/components/ui/separator/separator.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 |
21 |
--------------------------------------------------------------------------------
/src/lib/components/ui/sheet/index.ts:
--------------------------------------------------------------------------------
1 | import { Dialog as SheetPrimitive } from 'bits-ui';
2 | import Trigger from './sheet-trigger.svelte';
3 | import Close from './sheet-close.svelte';
4 | import Overlay from './sheet-overlay.svelte';
5 | import Content from './sheet-content.svelte';
6 | import Header from './sheet-header.svelte';
7 | import Footer from './sheet-footer.svelte';
8 | import Title from './sheet-title.svelte';
9 | import Description from './sheet-description.svelte';
10 |
11 | const Root = SheetPrimitive.Root;
12 | const Portal = SheetPrimitive.Portal;
13 |
14 | export {
15 | Root,
16 | Close,
17 | Trigger,
18 | Portal,
19 | Overlay,
20 | Content,
21 | Header,
22 | Footer,
23 | Title,
24 | Description,
25 | //
26 | Root as Sheet,
27 | Close as SheetClose,
28 | Trigger as SheetTrigger,
29 | Portal as SheetPortal,
30 | Overlay as SheetOverlay,
31 | Content as SheetContent,
32 | Header as SheetHeader,
33 | Footer as SheetFooter,
34 | Title as SheetTitle,
35 | Description as SheetDescription
36 | };
37 |
--------------------------------------------------------------------------------
/src/lib/components/ui/sheet/sheet-close.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/lib/components/ui/sheet/sheet-description.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 |
18 |
--------------------------------------------------------------------------------
/src/lib/components/ui/sheet/sheet-footer.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
19 | {@render children?.()}
20 |
21 |
--------------------------------------------------------------------------------
/src/lib/components/ui/sheet/sheet-header.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
19 | {@render children?.()}
20 |
21 |
--------------------------------------------------------------------------------
/src/lib/components/ui/sheet/sheet-overlay.svelte:
--------------------------------------------------------------------------------
1 |
13 |
14 |
23 |
--------------------------------------------------------------------------------
/src/lib/components/ui/sheet/sheet-title.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 |
18 |
--------------------------------------------------------------------------------
/src/lib/components/ui/sheet/sheet-trigger.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/lib/components/ui/sidebar/constants.ts:
--------------------------------------------------------------------------------
1 | export const SIDEBAR_COOKIE_NAME = 'sidebar:state';
2 | export const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
3 | export const SIDEBAR_WIDTH = '16rem';
4 | export const SIDEBAR_WIDTH_MOBILE = '18rem';
5 | export const SIDEBAR_WIDTH_ICON = '3rem';
6 | export const SIDEBAR_KEYBOARD_SHORTCUT = 'b';
7 |
--------------------------------------------------------------------------------
/src/lib/components/ui/sidebar/sidebar-content.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
23 | {@render children?.()}
24 |
25 |
--------------------------------------------------------------------------------
/src/lib/components/ui/sidebar/sidebar-footer.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
20 | {@render children?.()}
21 |
22 |
--------------------------------------------------------------------------------
/src/lib/components/ui/sidebar/sidebar-group-content.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
20 | {@render children?.()}
21 |
22 |
--------------------------------------------------------------------------------
/src/lib/components/ui/sidebar/sidebar-group.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
20 | {@render children?.()}
21 |
22 |
--------------------------------------------------------------------------------
/src/lib/components/ui/sidebar/sidebar-header.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
20 | {@render children?.()}
21 |
22 |
--------------------------------------------------------------------------------
/src/lib/components/ui/sidebar/sidebar-input.svelte:
--------------------------------------------------------------------------------
1 |
13 |
14 |
22 |
--------------------------------------------------------------------------------
/src/lib/components/ui/sidebar/sidebar-inset.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
23 | {@render children?.()}
24 |
25 |
--------------------------------------------------------------------------------
/src/lib/components/ui/sidebar/sidebar-menu-badge.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
28 | {@render children?.()}
29 |
30 |
--------------------------------------------------------------------------------
/src/lib/components/ui/sidebar/sidebar-menu-item.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
22 |
--------------------------------------------------------------------------------
/src/lib/components/ui/sidebar/sidebar-menu-skeleton.svelte:
--------------------------------------------------------------------------------
1 |
19 |
20 |
27 | {#if showIcon}
28 |
29 | {/if}
30 |
35 | {@render children?.()}
36 |
37 |
--------------------------------------------------------------------------------
/src/lib/components/ui/sidebar/sidebar-menu-sub-item.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
22 |
--------------------------------------------------------------------------------
/src/lib/components/ui/sidebar/sidebar-menu-sub.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
24 | {@render children?.()}
25 |
26 |
--------------------------------------------------------------------------------
/src/lib/components/ui/sidebar/sidebar-menu.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
20 | {@render children?.()}
21 |
22 |
--------------------------------------------------------------------------------
/src/lib/components/ui/sidebar/sidebar-separator.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
20 |
--------------------------------------------------------------------------------
/src/lib/components/ui/sidebar/sidebar-trigger.svelte:
--------------------------------------------------------------------------------
1 |
19 |
20 | {
28 | onclick?.(e);
29 | sidebar.toggle();
30 | }}
31 | {...restProps}
32 | >
33 |
34 | Toggle Sidebar
35 |
36 |
--------------------------------------------------------------------------------
/src/lib/components/ui/skeleton/index.ts:
--------------------------------------------------------------------------------
1 | import Root from './skeleton.svelte';
2 |
3 | export {
4 | Root,
5 | //
6 | Root as Skeleton
7 | };
8 |
--------------------------------------------------------------------------------
/src/lib/components/ui/skeleton/skeleton.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 |
18 |
--------------------------------------------------------------------------------
/src/lib/components/ui/snippet/index.ts:
--------------------------------------------------------------------------------
1 | import Snippet from './snippet.svelte';
2 |
3 | export { Snippet };
4 |
--------------------------------------------------------------------------------
/src/lib/components/ui/sonner/index.ts:
--------------------------------------------------------------------------------
1 | export { default as Toaster } from './sonner.svelte';
2 |
--------------------------------------------------------------------------------
/src/lib/components/ui/sonner/sonner.svelte:
--------------------------------------------------------------------------------
1 |
7 |
8 |
14 |
--------------------------------------------------------------------------------
/src/lib/components/ui/star-rating/index.ts:
--------------------------------------------------------------------------------
1 | export { default as Root } from './star-rating.svelte';
2 | export { default as Star } from './star-rating-star.svelte';
3 |
--------------------------------------------------------------------------------
/src/lib/components/ui/star-rating/star-rating.svelte:
--------------------------------------------------------------------------------
1 |
13 |
14 |
21 |
--------------------------------------------------------------------------------
/src/lib/components/ui/tabs/index.ts:
--------------------------------------------------------------------------------
1 | import Root from './tabs.svelte';
2 | import Content from './tabs-content.svelte';
3 | import List from './tabs-list.svelte';
4 | import Trigger from './tabs-trigger.svelte';
5 |
6 | export {
7 | Root,
8 | Content,
9 | List,
10 | Trigger,
11 | //
12 | Root as Tabs,
13 | Content as TabsContent,
14 | List as TabsList,
15 | Trigger as TabsTrigger
16 | };
17 |
--------------------------------------------------------------------------------
/src/lib/components/ui/tabs/tabs-content.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 |
18 |
--------------------------------------------------------------------------------
/src/lib/components/ui/tabs/tabs-list.svelte:
--------------------------------------------------------------------------------
1 |
7 |
8 |
17 |
--------------------------------------------------------------------------------
/src/lib/components/ui/tabs/tabs-trigger.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 |
21 |
--------------------------------------------------------------------------------
/src/lib/components/ui/tabs/tabs.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
20 |
--------------------------------------------------------------------------------
/src/lib/components/ui/tags-input/index.ts:
--------------------------------------------------------------------------------
1 | import TagsInput from './tags-input.svelte';
2 |
3 | export { TagsInput };
4 |
--------------------------------------------------------------------------------
/src/lib/components/ui/tags-input/tags-input-tag.svelte:
--------------------------------------------------------------------------------
1 |
13 |
14 |
18 |
19 | {value}
20 |
21 | onDelete(value)}>
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/lib/components/ui/tags-input/types.ts:
--------------------------------------------------------------------------------
1 | import type { HTMLInputAttributes } from 'svelte/elements';
2 |
3 | export interface TagsInputProps extends HTMLInputAttributes {
4 | value?: string[];
5 | class?: string;
6 | placeholder?: string;
7 | disabled?: boolean;
8 | validate?: (val: string, tags: string[]) => string | undefined;
9 | }
10 |
--------------------------------------------------------------------------------
/src/lib/components/ui/terminal/index.ts:
--------------------------------------------------------------------------------
1 | import Loop from './terminal-loop.svelte';
2 | import Root from './terminal.svelte';
3 | import TypingAnimation from './terminal-typing-animation.svelte';
4 | import AnimatedSpan from './terminal-animated-span.svelte';
5 | import Loading from './terminal-loading.svelte';
6 |
7 | export { Loop, Root, TypingAnimation, AnimatedSpan, Loading };
8 |
--------------------------------------------------------------------------------
/src/lib/components/ui/terminal/terminal-loop.svelte:
--------------------------------------------------------------------------------
1 |
24 |
25 | {#key loopIndex}
26 | {@render children?.()}
27 | {/key}
28 |
--------------------------------------------------------------------------------
/src/lib/components/ui/terminal/terminal-typing-animation.svelte:
--------------------------------------------------------------------------------
1 |
22 |
23 | {#if playAnimation}
24 | animation.onComplete?.()
29 | }}
30 | >
31 | {@render children?.()}
32 |
33 | {/if}
34 |
--------------------------------------------------------------------------------
/src/lib/components/ui/terminal/terminal.svelte:
--------------------------------------------------------------------------------
1 |
28 |
29 |
30 | {@render children?.()}
31 |
32 |
--------------------------------------------------------------------------------
/src/lib/components/ui/terminal/types.ts:
--------------------------------------------------------------------------------
1 | import type { WithChildren } from 'bits-ui';
2 |
3 | export type TerminalAnimationProps = WithChildren<{
4 | delay?: number;
5 | class?: string;
6 | }>;
7 |
--------------------------------------------------------------------------------
/src/lib/components/ui/textarea/index.ts:
--------------------------------------------------------------------------------
1 | import Root from './textarea.svelte';
2 |
3 | export {
4 | Root,
5 | //
6 | Root as Textarea
7 | };
8 |
--------------------------------------------------------------------------------
/src/lib/components/ui/textarea/textarea.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
23 |
--------------------------------------------------------------------------------
/src/lib/components/ui/theme-selector/index.ts:
--------------------------------------------------------------------------------
1 | import ThemeSelector from './theme-selector.svelte';
2 |
3 | export { ThemeSelector };
4 |
--------------------------------------------------------------------------------
/src/lib/components/ui/toc/index.ts:
--------------------------------------------------------------------------------
1 | import Root from './toc.svelte';
2 |
3 | export { Root };
4 |
--------------------------------------------------------------------------------
/src/lib/components/ui/toc/toc.svelte:
--------------------------------------------------------------------------------
1 |
15 |
16 |
17 | {#each toc as heading, i (i)}
18 |
23 | {#if heading.id}
24 |
25 | {heading.label}
26 |
27 | {:else}
28 | {heading.label}
29 | {/if}
30 |
31 | {#if heading.children.length > 0}
32 |
33 | {/if}
34 | {/each}
35 |
36 |
--------------------------------------------------------------------------------
/src/lib/components/ui/tooltip/index.ts:
--------------------------------------------------------------------------------
1 | import { Tooltip as TooltipPrimitive } from 'bits-ui';
2 | import Trigger from './tooltip-trigger.svelte';
3 | import Content from './tooltip-content.svelte';
4 |
5 | const Root = TooltipPrimitive.Root;
6 | const Provider = TooltipPrimitive.Provider;
7 | const Portal = TooltipPrimitive.Portal;
8 |
9 | export {
10 | Root,
11 | Trigger,
12 | Content,
13 | Provider,
14 | Portal,
15 | //
16 | Root as Tooltip,
17 | Content as TooltipContent,
18 | Trigger as TooltipTrigger,
19 | Provider as TooltipProvider,
20 | Portal as TooltipPortal
21 | };
22 |
--------------------------------------------------------------------------------
/src/lib/components/ui/tooltip/tooltip-trigger.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/lib/components/ui/tree-view/index.ts:
--------------------------------------------------------------------------------
1 | import TreeView from './tree-view.svelte';
2 | import TreeViewFile from './tree-view-file.svelte';
3 | import TreeViewFolder from './tree-view-folder.svelte';
4 |
5 | export {
6 | TreeView,
7 | TreeViewFile,
8 | TreeViewFolder,
9 |
10 | // ...
11 | TreeView as Root,
12 | TreeViewFile as File,
13 | TreeViewFolder as Folder
14 | };
15 |
--------------------------------------------------------------------------------
/src/lib/components/ui/tree-view/tree-view-file.svelte:
--------------------------------------------------------------------------------
1 |
14 |
15 |
16 | {#if icon}
17 | {@render icon({ name })}
18 | {:else}
19 |
20 | {/if}
21 | {name}
22 |
23 |
--------------------------------------------------------------------------------
/src/lib/components/ui/tree-view/tree-view.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 |
14 | {@render children?.()}
15 |
16 |
--------------------------------------------------------------------------------
/src/lib/components/ui/window/index.ts:
--------------------------------------------------------------------------------
1 | import Window from './window.svelte';
2 |
3 | export { Window };
4 |
--------------------------------------------------------------------------------
/src/lib/components/ui/window/window.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
20 |
21 | {@render children?.()}
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/lib/context.ts:
--------------------------------------------------------------------------------
1 | import { Context } from 'runed';
2 | import type { UseBoolean } from './hooks/use-boolean.svelte';
3 |
4 | export const commandContext = new Context('command-menu-context');
5 |
--------------------------------------------------------------------------------
/src/lib/hooks/is-mobile.svelte.ts:
--------------------------------------------------------------------------------
1 | import { MediaQuery } from 'svelte/reactivity';
2 |
3 | const MOBILE_BREAKPOINT = 768;
4 |
5 | export class IsMobile extends MediaQuery {
6 | constructor() {
7 | super(`max-width: ${MOBILE_BREAKPOINT - 1}px`);
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/lib/utils.ts:
--------------------------------------------------------------------------------
1 | import { clsx, type ClassValue } from 'clsx';
2 | import { twMerge } from 'tailwind-merge';
3 |
4 | export function cn(...inputs: ClassValue[]) {
5 | return twMerge(clsx(inputs));
6 | }
7 |
8 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
9 | export type WithoutChild = T extends { child?: any } ? Omit : T;
10 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
11 | export type WithoutChildren = T extends { children?: any } ? Omit : T;
12 | export type WithoutChildrenOrChild = WithoutChildren>;
13 | export type WithElementRef = T & { ref?: U | null };
14 |
--------------------------------------------------------------------------------
/src/lib/utils/box.ts:
--------------------------------------------------------------------------------
1 | import type { ReadableBox, WritableBox } from 'svelte-toolbelt';
2 |
3 | export type Box = ReadableBox | WritableBox;
4 |
5 | export type WritableBoxedValues = {
6 | [K in keyof T]: WritableBox;
7 | };
8 |
9 | export type ReadableBoxedValues = {
10 | [K in keyof T]: ReadableBox;
11 | };
12 |
--------------------------------------------------------------------------------
/src/lib/utils/is-number.ts:
--------------------------------------------------------------------------------
1 | /*
2 | Installed from @ieedan/std
3 | */
4 |
5 | /** Checks if provided value is actually a number.
6 | *
7 | * @param num value to check
8 | * @returns
9 | *
10 | * ## Usage
11 | *
12 | * ```ts
13 | * isNumber("2"); // true
14 | * isNumber("1.11"); // true
15 | * isNumber("0xff"); // true
16 | *
17 | * isNumber("two"); // false
18 | * isNumber({ two: 2 }); // false
19 | * isNumber(Number.POSITIVE_INFINITY); // false
20 | * ```
21 | */
22 | export function isNumber(num: unknown): boolean {
23 | if (typeof num === 'number') return num - num === 0;
24 |
25 | if (typeof num === 'string' && num.trim() !== '') return Number.isFinite(+num);
26 |
27 | return false;
28 | }
29 |
--------------------------------------------------------------------------------
/src/lib/utils/sleep.ts:
--------------------------------------------------------------------------------
1 | /*
2 | Installed from @ieedan/std
3 | */
4 |
5 | /** Await this to pause execution until the duration has passed.
6 | *
7 | * @param durationMs The duration in ms until the sleep in over
8 | * @returns
9 | *
10 | * ## Usage
11 | * ```ts
12 | * console.log(Date.now()) // 1725739228744
13 | *
14 | * await sleep(1000);
15 | *
16 | * console.log(Date.now()) // 1725739229744
17 | * ```
18 | */
19 | export function sleep(durationMs: number): Promise {
20 | return new Promise((res) => setTimeout(res, durationMs));
21 | }
22 |
--------------------------------------------------------------------------------
/src/lib/utils/types.ts:
--------------------------------------------------------------------------------
1 | /*
2 | Installed from @ieedan/std
3 | */
4 |
5 | /** Allows you to have autocomplete on a string while still accepting any string value.
6 | *
7 | * ## Usage
8 | * ```ts
9 | * type Fruits = LooseAutocomplete<'apple' | 'orange' | 'pear'>;
10 | *
11 | * // you will still get autocomplete here
12 | * let fruit: Fruits = 'apple'; // valid
13 | * fruit = 'banana'; // valid
14 | * ```
15 | */
16 | export type LooseAutocomplete = T | (string & {});
17 |
18 | /** Flattens a complex object type down into a single object.
19 | * Super useful when using joins with `Omit` and other helpers without needing to reveal the base type.
20 | */
21 | export type Prettify = {
22 | [K in keyof T]: T[K];
23 | } & {};
24 |
--------------------------------------------------------------------------------
/src/lib/utils/utils.ts:
--------------------------------------------------------------------------------
1 | import { type ClassValue, clsx } from 'clsx';
2 | import { twMerge } from 'tailwind-merge';
3 |
4 | export function cn(...inputs: ClassValue[]) {
5 | return twMerge(clsx(inputs));
6 | }
7 |
8 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
9 | export type WithoutChild = T extends { child?: any } ? Omit : T;
10 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
11 | export type WithoutChildren = T extends { children?: any } ? Omit : T;
12 | export type WithoutChildrenOrChild = WithoutChildren>;
13 | export type WithElementRef = T & { ref?: U | null };
14 |
--------------------------------------------------------------------------------
/src/routes/actions/active/examples.ts:
--------------------------------------------------------------------------------
1 | import Basic from './basic.svelte';
2 | import basicRaw from './basic.svelte?raw';
3 |
4 | const examples = {
5 | basic: {
6 | code: basicRaw,
7 | Component: Basic
8 | }
9 | };
10 |
11 | export { examples };
12 |
--------------------------------------------------------------------------------
/src/routes/actions/shortcut/basic.svelte:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 | toast.success('You pressed Ctrl + 1')
15 | }}
16 | />
17 |
18 |
19 | + 1
20 |
21 |
--------------------------------------------------------------------------------
/src/routes/actions/shortcut/examples.ts:
--------------------------------------------------------------------------------
1 | import Basic from './basic.svelte';
2 | import basicRaw from './basic.svelte?raw';
3 |
4 | const examples = {
5 | basic: {
6 | code: basicRaw,
7 | Component: Basic
8 | }
9 | };
10 |
11 | export { examples };
12 |
--------------------------------------------------------------------------------
/src/routes/components/+page.server.ts:
--------------------------------------------------------------------------------
1 | import { redirect } from '@sveltejs/kit';
2 |
3 | // just in case anyone linked to the old path
4 |
5 | export function load() {
6 | throw redirect(307, '/components/avatar-group');
7 | }
8 |
--------------------------------------------------------------------------------
/src/routes/components/+page.svelte:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ieedan/shadcn-svelte-extras/fd06d9df74e6a1a25ff1ef00b17f5dd9cf1b92fd/src/routes/components/+page.svelte
--------------------------------------------------------------------------------
/src/routes/components/avatar-group/basic.svelte:
--------------------------------------------------------------------------------
1 |
19 |
20 |
21 | {#each members as member (member.username)}
22 |
23 |
24 |
25 | {member.username[0]}
26 |
27 |
28 | {/each}
29 |
30 |
31 |
--------------------------------------------------------------------------------
/src/routes/components/avatar-group/examples.ts:
--------------------------------------------------------------------------------
1 | import Basic from './basic.svelte';
2 | import basicRaw from './basic.svelte?raw';
3 | import Vertical from './vertical.svelte';
4 | import verticalRaw from './vertical.svelte?raw';
5 |
6 | const examples = {
7 | basic: {
8 | code: basicRaw,
9 | Component: Basic
10 | },
11 | vertical: {
12 | code: verticalRaw,
13 | Component: Vertical
14 | }
15 | };
16 |
17 | export { examples };
18 |
--------------------------------------------------------------------------------
/src/routes/components/avatar-group/vertical.svelte:
--------------------------------------------------------------------------------
1 |
19 |
20 |
21 | {#each members as member (member.username)}
22 |
23 |
24 |
25 | {member.username[0]}
26 |
27 |
28 | {/each}
29 |
30 |
31 |
--------------------------------------------------------------------------------
/src/routes/components/button/+page.svelte:
--------------------------------------------------------------------------------
1 |
7 |
8 | The same old button you know from shadcn-svelte with a few extra touches.
9 | Basic
10 |
11 |
12 |
13 |
14 | Loading
15 |
16 |
17 |
18 | onClickPromise
19 |
20 | You can also pass a promise to onClickPromise to show a loading state until it
21 | resolves.
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/routes/components/button/basic.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 | Save
6 |
--------------------------------------------------------------------------------
/src/routes/components/button/examples.ts:
--------------------------------------------------------------------------------
1 | import Basic from './basic.svelte';
2 | import basicRaw from './basic.svelte?raw';
3 | import Loading from './loading.svelte';
4 | import loadingRaw from './loading.svelte?raw';
5 | import OnClickPromise from './on-click-promise.svelte';
6 | import onClickPromiseRaw from './on-click-promise.svelte?raw';
7 |
8 | const examples = {
9 | basic: {
10 | code: basicRaw,
11 | Component: Basic
12 | },
13 | loading: {
14 | code: loadingRaw,
15 | Component: Loading
16 | },
17 | onClickPromise: {
18 | code: onClickPromiseRaw,
19 | Component: OnClickPromise
20 | }
21 | };
22 |
23 | export { examples };
24 |
--------------------------------------------------------------------------------
/src/routes/components/button/loading.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 | Hello
6 |
--------------------------------------------------------------------------------
/src/routes/components/button/on-click-promise.svelte:
--------------------------------------------------------------------------------
1 |
9 |
10 | Save
11 |
--------------------------------------------------------------------------------
/src/routes/components/chat/examples.ts:
--------------------------------------------------------------------------------
1 | import Basic from './basic.svelte';
2 | import basicRaw from './basic.svelte?raw';
3 |
4 | const examples = {
5 | basic: {
6 | code: basicRaw,
7 | Component: Basic
8 | }
9 | };
10 |
11 | export { examples };
12 |
--------------------------------------------------------------------------------
/src/routes/components/chat/types.ts:
--------------------------------------------------------------------------------
1 | export type User = {
2 | id: string;
3 | username: string;
4 | name: string;
5 | img: string;
6 | };
7 |
8 | export type Message = {
9 | senderId: string;
10 | message: string;
11 | sentAt: string;
12 | };
13 |
--------------------------------------------------------------------------------
/src/routes/components/chat/utils.ts:
--------------------------------------------------------------------------------
1 | export const formatShortTime = (date: Date) => {
2 | return date.toLocaleTimeString('en-US', {
3 | hour: 'numeric',
4 | minute: '2-digit',
5 | hour12: true
6 | });
7 | };
8 |
9 | export const initials = (name: string) =>
10 | name
11 | .split(' ')
12 | .map((n) => n[0])
13 | .join('');
14 |
--------------------------------------------------------------------------------
/src/routes/components/code/basic.svelte:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/routes/components/code/examples.ts:
--------------------------------------------------------------------------------
1 | import Basic from './basic.svelte';
2 | import basicRaw from './basic.svelte?raw';
3 | import NoLineNumbers from './no-line-numbers.svelte';
4 | import noLineNumbersRaw from './no-line-numbers.svelte?raw';
5 | import Variants from './variants.svelte';
6 | import variantsRaw from './variants.svelte?raw';
7 | import HighlightLines from './highlight-lines.svelte';
8 | import highlightLinesRaw from './highlight-lines.svelte?raw';
9 | import Overflow from './overflow.svelte';
10 | import overflowRaw from './overflow.svelte?raw';
11 |
12 | const examples = {
13 | basic: {
14 | code: basicRaw,
15 | Component: Basic
16 | },
17 | noLineNumbers: {
18 | code: noLineNumbersRaw,
19 | Component: NoLineNumbers
20 | },
21 | variants: {
22 | code: variantsRaw,
23 | Component: Variants
24 | },
25 | highlightLines: {
26 | code: highlightLinesRaw,
27 | Component: HighlightLines
28 | },
29 | overflow: {
30 | code: overflowRaw,
31 | Component: Overflow
32 | }
33 | };
34 |
35 | export { examples };
36 |
--------------------------------------------------------------------------------
/src/routes/components/code/highlight-lines.svelte:
--------------------------------------------------------------------------------
1 |
20 |
21 |
22 |
30 |
31 |
--------------------------------------------------------------------------------
/src/routes/components/code/no-line-numbers.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/routes/components/code/overflow.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/src/routes/components/code/variants.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
13 |
19 | Button
20 | `}
21 | />
22 |
23 |
--------------------------------------------------------------------------------
/src/routes/components/copy-button/+page.svelte:
--------------------------------------------------------------------------------
1 |
7 |
8 | Basic
9 |
10 |
11 |
12 |
13 | Custom Icon
14 |
15 |
16 |
17 | With Text
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/routes/components/copy-button/basic.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/routes/components/copy-button/examples.ts:
--------------------------------------------------------------------------------
1 | import Basic from './basic.svelte';
2 | import basicRaw from './basic.svelte?raw';
3 | import Icon from './icon.svelte';
4 | import iconRaw from './icon.svelte?raw';
5 | import WithText from './with-text.svelte';
6 | import withTextRaw from './with-text.svelte?raw';
7 |
8 | const examples = {
9 | basic: {
10 | code: basicRaw,
11 | Component: Basic
12 | },
13 | icon: {
14 | code: iconRaw,
15 | Component: Icon
16 | },
17 | withText: {
18 | code: withTextRaw,
19 | Component: WithText
20 | }
21 | };
22 |
23 | export { examples };
24 |
--------------------------------------------------------------------------------
/src/routes/components/copy-button/icon.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 | {#snippet icon()}
8 |
9 | {/snippet}
10 |
11 |
--------------------------------------------------------------------------------
/src/routes/components/copy-button/with-text.svelte:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 | {#snippet icon()}
10 |
11 | {/snippet}
12 | {command}
13 |
14 |
--------------------------------------------------------------------------------
/src/routes/components/field-set/+page.svelte:
--------------------------------------------------------------------------------
1 |
7 |
8 | Basic
9 |
10 |
11 |
12 |
13 | Destructive
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/routes/components/field-set/basic.svelte:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 | Username
13 |
14 |
15 |
16 |
17 |
18 | Save your username.
19 | Save
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/routes/components/field-set/destructive.svelte:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 | Project Name
13 |
14 |
15 |
16 |
17 |
18 | Rename your project.
19 | Rename
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/routes/components/field-set/examples.ts:
--------------------------------------------------------------------------------
1 | import Basic from './basic.svelte';
2 | import basicRaw from './basic.svelte?raw';
3 | import Destructive from './destructive.svelte';
4 | import destructiveRaw from './destructive.svelte?raw';
5 |
6 | const examples = {
7 | basic: {
8 | code: basicRaw,
9 | Component: Basic
10 | },
11 | destructive: {
12 | code: destructiveRaw,
13 | Component: Destructive
14 | }
15 | };
16 |
17 | export { examples };
18 |
--------------------------------------------------------------------------------
/src/routes/components/file-drop-zone/+page.server.ts:
--------------------------------------------------------------------------------
1 | import { fail, message, superValidate } from 'sveltekit-superforms';
2 | import { valibot } from 'sveltekit-superforms/adapters';
3 | import { schema } from './schema';
4 |
5 | export const load = async () => {
6 | return {
7 | form: await superValidate({}, valibot(schema))
8 | };
9 | };
10 |
11 | export const actions = {
12 | default: async ({ request }) => {
13 | const form = await superValidate(request, valibot(schema));
14 |
15 | if (!form.valid) {
16 | return fail(400, { form });
17 | }
18 |
19 | return message(form, 'Posted!');
20 | }
21 | };
22 |
--------------------------------------------------------------------------------
/src/routes/components/file-drop-zone/examples.ts:
--------------------------------------------------------------------------------
1 | import Basic from './basic.svelte';
2 | import basicRaw from './basic.svelte?raw';
3 | import Form from './form.svelte';
4 | import formRaw from './form.svelte?raw';
5 | import schemaRaw from './schema.ts?raw';
6 |
7 | const examples = {
8 | basic: {
9 | code: basicRaw,
10 | Component: Basic
11 | },
12 | form: {
13 | code: formRaw,
14 | Component: Form
15 | },
16 | schema: schemaRaw
17 | };
18 |
19 | export { examples };
20 |
--------------------------------------------------------------------------------
/src/routes/components/file-drop-zone/schema.ts:
--------------------------------------------------------------------------------
1 | import * as v from 'valibot';
2 | import { MEGABYTE } from '$lib/components/ui/file-drop-zone';
3 |
4 | export const schema = v.object({
5 | attachments: v.array(v.pipe(v.file(), v.maxSize(MEGABYTE * 2)))
6 | });
7 |
8 | export type Schema = v.InferInput;
9 |
--------------------------------------------------------------------------------
/src/routes/components/image-cropper/basic.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 | {
9 | // if you need the file for a form you can call getFileFromUrl with the cropped url
10 | const file = await getFileFromUrl(url);
11 |
12 | console.log(file);
13 | }}
14 | >
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/routes/components/image-cropper/custom-preview.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 | {#snippet child({ src })}
9 |
10 | {/snippet}
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/routes/components/image-cropper/examples.ts:
--------------------------------------------------------------------------------
1 | import Basic from './basic.svelte';
2 | import basicRaw from './basic.svelte?raw';
3 | import SquarePreview from './square-preview.svelte';
4 | import squarePreviewRaw from './square-preview.svelte?raw';
5 | import NoDefaultImage from './no-default-image.svelte';
6 | import noDefaultImageRaw from './no-default-image.svelte?raw';
7 | import CustomTrigger from './custom-trigger.svelte';
8 | import customTriggerRaw from './custom-trigger.svelte?raw';
9 | import CustomPreview from './custom-preview.svelte';
10 | import customPreviewRaw from './custom-preview.svelte?raw';
11 |
12 | const examples = {
13 | basic: {
14 | code: basicRaw,
15 | Component: Basic
16 | },
17 | squarePreview: {
18 | code: squarePreviewRaw,
19 | Component: SquarePreview
20 | },
21 | noDefaultImage: {
22 | code: noDefaultImageRaw,
23 | Component: NoDefaultImage
24 | },
25 | customTrigger: {
26 | code: customTriggerRaw,
27 | Component: CustomTrigger
28 | },
29 | customPreview: {
30 | code: customPreviewRaw,
31 | Component: CustomPreview
32 | }
33 | };
34 |
35 | export { examples };
36 |
--------------------------------------------------------------------------------
/src/routes/components/image-cropper/no-default-image.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/routes/components/image-cropper/square-preview.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/routes/components/ipv4address-input/+page.svelte:
--------------------------------------------------------------------------------
1 |
7 |
8 | Basic
9 |
10 |
11 |
12 |
13 | Placeholder
14 |
15 |
16 |
17 | Reactive
18 |
19 |
20 |
21 | Validation
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/routes/components/ipv4address-input/basic.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 | IP Address
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/routes/components/ipv4address-input/examples.ts:
--------------------------------------------------------------------------------
1 | import Basic from './basic.svelte';
2 | import basicRaw from './basic.svelte?raw';
3 | import Placeholder from './placeholder.svelte';
4 | import placeholderRaw from './placeholder.svelte?raw';
5 | import Reactive from './reactive.svelte';
6 | import reactiveRaw from './reactive.svelte?raw';
7 | import Valid from './valid.svelte';
8 | import validRaw from './valid.svelte?raw';
9 |
10 | const examples = {
11 | basic: {
12 | code: basicRaw,
13 | Component: Basic
14 | },
15 | placeholder: {
16 | code: placeholderRaw,
17 | Component: Placeholder
18 | },
19 | reactive: {
20 | code: reactiveRaw,
21 | Component: Reactive
22 | },
23 | valid: {
24 | code: validRaw,
25 | Component: Valid
26 | }
27 | };
28 |
29 | export { examples };
30 |
--------------------------------------------------------------------------------
/src/routes/components/ipv4address-input/placeholder.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 | IP Address
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/routes/components/ipv4address-input/reactive.svelte:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 | IP Address
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/routes/components/ipv4address-input/valid.svelte:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 | IP Address
10 |
11 |
12 |
13 | Valid:
14 |
15 | {valid}
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/routes/components/kbd/+page.svelte:
--------------------------------------------------------------------------------
1 |
7 |
8 | Basic
9 |
10 |
11 |
12 |
13 | Sizes
14 |
15 |
16 |
17 | Variants
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/routes/components/kbd/basic.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 | + K
9 |
10 |
--------------------------------------------------------------------------------
/src/routes/components/kbd/examples.ts:
--------------------------------------------------------------------------------
1 | import Basic from './basic.svelte';
2 | import basicRaw from './basic.svelte?raw';
3 | import Sizes from './sizes.svelte';
4 | import sizesRaw from './sizes.svelte?raw';
5 | import Variants from './variants.svelte';
6 | import variantsRaw from './variants.svelte?raw';
7 |
8 | const examples = {
9 | basic: {
10 | code: basicRaw,
11 | Component: Basic
12 | },
13 | sizes: {
14 | code: sizesRaw,
15 | Component: Sizes
16 | },
17 | variants: {
18 | code: variantsRaw,
19 | Component: Variants
20 | }
21 | };
22 |
23 | export { examples };
24 |
--------------------------------------------------------------------------------
/src/routes/components/kbd/sizes.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 | A
7 | B
8 | C
9 |
10 |
--------------------------------------------------------------------------------
/src/routes/components/kbd/variants.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 | A
8 | B
9 | C
10 |
11 |
12 | A
13 | B
14 | C
15 |
16 |
17 | A
18 | B
19 | C
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/routes/components/language-switcher/+page.svelte:
--------------------------------------------------------------------------------
1 |
8 |
9 | Basic
10 |
11 |
12 |
13 |
14 |
15 | Ghost + Align
16 |
17 |
18 |
19 |
20 | Paraglide Integration
21 |
22 | Example of how to integrate with
27 | ParaglideJS
28 | :
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/src/routes/components/language-switcher/basic.svelte:
--------------------------------------------------------------------------------
1 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/routes/components/language-switcher/examples.ts:
--------------------------------------------------------------------------------
1 | import Basic from './basic.svelte';
2 | import basicRaw from './basic.svelte?raw';
3 | import Variants from './variants.svelte';
4 | import variantsRaw from './variants.svelte?raw';
5 | import Paraglide from './paraglide.svelte';
6 | import paraglideRaw from './paraglide.svelte?raw';
7 |
8 | const examples = {
9 | basic: {
10 | code: basicRaw,
11 | Component: Basic
12 | },
13 | variants: {
14 | code: variantsRaw,
15 | Component: Variants
16 | },
17 | paraglide: {
18 | code: paraglideRaw,
19 | Component: Paraglide
20 | }
21 | };
22 |
23 | export { examples };
24 |
--------------------------------------------------------------------------------
/src/routes/components/language-switcher/paraglide.svelte:
--------------------------------------------------------------------------------
1 |
26 |
27 |
28 | {
32 | if (isLocale(code)) setLocale(code);
33 | }}
34 | />
35 |
36 | {m.example_message()}
37 |
38 |
--------------------------------------------------------------------------------
/src/routes/components/language-switcher/variants.svelte:
--------------------------------------------------------------------------------
1 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/routes/components/light-switch/+page.svelte:
--------------------------------------------------------------------------------
1 |
7 |
8 | Basic
9 |
10 |
11 |
12 |
13 | Ghost
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/routes/components/light-switch/basic.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/routes/components/light-switch/examples.ts:
--------------------------------------------------------------------------------
1 | import Basic from './basic.svelte';
2 | import basicRaw from './basic.svelte?raw';
3 | import Variants from './variants.svelte';
4 | import variantsRaw from './variants.svelte?raw';
5 |
6 | const examples = {
7 | basic: {
8 | code: basicRaw,
9 | Component: Basic
10 | },
11 | variants: {
12 | code: variantsRaw,
13 | Component: Variants
14 | }
15 | };
16 |
17 | export { examples };
18 |
--------------------------------------------------------------------------------
/src/routes/components/light-switch/variants.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/routes/components/link/+page.svelte:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
12 |
13 | Usage
14 |
15 |
18 | import { Link } from '$lib/components/ui/link';
19 | \<\/script\>
20 |
21 | Hello`}
22 | />
23 |
24 |
--------------------------------------------------------------------------------
/src/routes/components/link/basic.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 | Crafted by
7 | huntabyte, enhanced by
8 | ieedan.
9 |
10 |
--------------------------------------------------------------------------------
/src/routes/components/link/examples.ts:
--------------------------------------------------------------------------------
1 | import Basic from './basic.svelte';
2 | import basicRaw from './basic.svelte?raw';
3 |
4 | const examples = {
5 | basic: {
6 | code: basicRaw,
7 | Component: Basic
8 | }
9 | };
10 |
11 | export { examples };
12 |
--------------------------------------------------------------------------------
/src/routes/components/modal/+page.svelte:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
12 |
13 | Usage
14 | The modal component can be composed just like a dialog or drawer component.
15 |
16 |
19 | import * as Modal from "$lib/components/ui/modal";
20 | \<\/script\>
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | `}
32 | />
33 |
34 |
--------------------------------------------------------------------------------
/src/routes/components/modal/basic.svelte:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 | Edit Profile
10 |
11 |
12 | Edit Profile
13 |
14 | Make changes to your profile here. Click save when you're done.
15 |
16 |
17 |
27 |
28 | Save Changes
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/src/routes/components/modal/examples.ts:
--------------------------------------------------------------------------------
1 | import Basic from './basic.svelte';
2 | import basicRaw from './basic.svelte?raw';
3 |
4 | const examples = {
5 | basic: {
6 | code: basicRaw,
7 | Component: Basic
8 | }
9 | };
10 |
11 | export { examples };
12 |
--------------------------------------------------------------------------------
/src/routes/components/nlp-date-input/+page.svelte:
--------------------------------------------------------------------------------
1 |
7 |
8 | Allows you to provide a date in natural language and helps by giving suggestions.
9 |
10 |
11 |
12 |
13 | Min/Max
14 |
15 | You may want to limit what suggestions are actually presented to the user so that they don't
16 | schedule an appointment 30 years from now. You can do this with the
17 | min and max props.
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/routes/components/nlp-date-input/basic.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
9 | toast.success(label, {
10 | description: `${date.toDateString()} ${date.toLocaleTimeString()}`
11 | })}
12 | />
13 |
14 |
--------------------------------------------------------------------------------
/src/routes/components/nlp-date-input/examples.ts:
--------------------------------------------------------------------------------
1 | import Basic from './basic.svelte';
2 | import basicRaw from './basic.svelte?raw';
3 | import MinMax from './min-max.svelte';
4 | import minMaxRaw from './min-max.svelte?raw';
5 |
6 | const examples = {
7 | basic: {
8 | code: basicRaw,
9 | Component: Basic
10 | },
11 | minMax: {
12 | code: minMaxRaw,
13 | Component: MinMax
14 | }
15 | };
16 |
17 | export { examples };
18 |
--------------------------------------------------------------------------------
/src/routes/components/nlp-date-input/min-max.svelte:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
14 | toast.success(label, {
15 | description: `${date.toDateString()} ${date.toLocaleTimeString()}`
16 | })}
17 | />
18 |
19 |
--------------------------------------------------------------------------------
/src/routes/components/phone-input/basic.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
10 |
--------------------------------------------------------------------------------
/src/routes/components/phone-input/custom-ordering.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
Phone Number
8 |
{
11 | if (a.iso2 == 'US') return -1;
12 | if (b.iso2 == 'US') return 1;
13 | if (a.iso2 == 'CN') return -1;
14 | if (b.iso2 == 'CN') return 1;
15 |
16 | return a.name.localeCompare(b.name);
17 | }}
18 | />
19 |
20 |
--------------------------------------------------------------------------------
/src/routes/components/phone-input/default-country.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
10 |
--------------------------------------------------------------------------------
/src/routes/components/phone-input/default-value.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
10 |
--------------------------------------------------------------------------------
/src/routes/components/phone-input/examples.ts:
--------------------------------------------------------------------------------
1 | import Basic from './basic.svelte';
2 | import basicRaw from './basic.svelte?raw';
3 | import DefaultCountry from './default-country.svelte';
4 | import defaultCountryRaw from './default-country.svelte?raw';
5 | import DefaultValue from './default-value.svelte';
6 | import defaultValueRaw from './default-value.svelte?raw';
7 | import CustomOrdering from './custom-ordering.svelte';
8 | import customOrderingRaw from './custom-ordering.svelte?raw';
9 |
10 | const examples = {
11 | basic: {
12 | code: basicRaw,
13 | Component: Basic
14 | },
15 | defaultCountry: {
16 | code: defaultCountryRaw,
17 | Component: DefaultCountry
18 | },
19 | defaultValue: {
20 | code: defaultValueRaw,
21 | Component: DefaultValue
22 | },
23 | customOrdering: {
24 | code: customOrderingRaw,
25 | Component: CustomOrdering
26 | }
27 | };
28 |
29 | export { examples };
30 |
--------------------------------------------------------------------------------
/src/routes/components/pm-command/basic.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/routes/components/pm-command/commands.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
9 |
--------------------------------------------------------------------------------
/src/routes/components/pm-command/customize-agents.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
10 |
--------------------------------------------------------------------------------
/src/routes/components/pm-command/overflow.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
20 |
--------------------------------------------------------------------------------
/src/routes/components/pm-command/persisted-pm.svelte:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/routes/components/pm-command/variants.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/routes/components/snippet/+page.svelte:
--------------------------------------------------------------------------------
1 |
7 |
8 | Basic
9 |
10 |
11 |
12 |
13 | Variants
14 |
15 |
16 |
17 | Multiline
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/routes/components/snippet/basic.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/routes/components/snippet/examples.ts:
--------------------------------------------------------------------------------
1 | import Basic from './basic.svelte';
2 | import basicRaw from './basic.svelte?raw';
3 | import Variants from './variants.svelte';
4 | import variantsRaw from './variants.svelte?raw';
5 | import Multiline from './multiline.svelte';
6 | import multilineRaw from './multiline.svelte?raw';
7 |
8 | const examples = {
9 | basic: {
10 | code: basicRaw,
11 | Component: Basic
12 | },
13 | variants: {
14 | code: variantsRaw,
15 | Component: Variants
16 | },
17 | multiline: {
18 | code: multilineRaw,
19 | Component: Multiline
20 | }
21 | };
22 |
23 | export { examples };
24 |
--------------------------------------------------------------------------------
/src/routes/components/snippet/multiline.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/routes/components/snippet/variants.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/routes/components/star-rating/basic.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 | {#snippet children({ items })}
10 | {#each items as item (item.index)}
11 |
12 | {/each}
13 | {/snippet}
14 |
15 | Rating is {value}
16 |
17 |
--------------------------------------------------------------------------------
/src/routes/components/star-rating/custom-color.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 | {#snippet children({ items })}
7 | {#each items as item (item.index)}
8 |
9 | {/each}
10 | {/snippet}
11 |
12 |
--------------------------------------------------------------------------------
/src/routes/components/star-rating/custom-size.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 | {#snippet children({ items })}
7 | {#each items as item (item.index)}
8 |
9 | {/each}
10 | {/snippet}
11 |
12 |
--------------------------------------------------------------------------------
/src/routes/components/star-rating/custom-stars.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 | {#snippet children({ items })}
7 | {#each items as item (item.index)}
8 |
9 | {/each}
10 | {/snippet}
11 |
12 |
--------------------------------------------------------------------------------
/src/routes/components/star-rating/disabled.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 | {#snippet children({ items })}
7 | {#each items as item (item.index)}
8 |
9 | {/each}
10 | {/snippet}
11 |
12 |
--------------------------------------------------------------------------------
/src/routes/components/star-rating/half-rating.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 | {#snippet children({ items })}
11 | {#each items as item (item.index)}
12 |
13 | {/each}
14 | {/snippet}
15 |
16 | Rating is {value}
17 |
18 |
19 | تقييم بالنجوم (RTL)
20 |
21 | {#snippet children({ items })}
22 | {#each items as item (item.index)}
23 |
24 | {/each}
25 | {/snippet}
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/src/routes/components/star-rating/readonly.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 | {#snippet children({ items })}
7 | {#each items as item (item.index)}
8 |
9 | {/each}
10 | {/snippet}
11 |
12 |
--------------------------------------------------------------------------------
/src/routes/components/tags-input/basic.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/routes/components/tags-input/custom-validate.ts:
--------------------------------------------------------------------------------
1 | import type { TagsInputProps } from '$lib/components/ui/tags-input/types';
2 |
3 | export const customValidate: TagsInputProps['validate'] = (val, tags) => {
4 | // trim and convert to lowercase
5 | const transformed = val.trim().toLowerCase();
6 |
7 | // disallow empties
8 | if (transformed.length === 0) return undefined;
9 |
10 | // disallow duplicates
11 | if (tags.find((t) => transformed === t.toLowerCase())) return undefined;
12 |
13 | return transformed;
14 | };
15 |
--------------------------------------------------------------------------------
/src/routes/components/tags-input/examples.ts:
--------------------------------------------------------------------------------
1 | import Basic from './basic.svelte';
2 | import basicRaw from './basic.svelte?raw';
3 | import customValidateCode from './custom-validate?raw';
4 | import Lowercase from './lowercase.svelte';
5 | import lowercaseRaw from './lowercase.svelte?raw';
6 |
7 | const examples = {
8 | basic: {
9 | code: basicRaw,
10 | Component: Basic
11 | },
12 | customValidateCode,
13 | lowercase: {
14 | code: lowercaseRaw,
15 | Component: Lowercase
16 | }
17 | };
18 |
19 | export { examples };
20 |
--------------------------------------------------------------------------------
/src/routes/components/tags-input/lowercase.svelte:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/routes/components/terminal/examples.ts:
--------------------------------------------------------------------------------
1 | import Basic from './basic.svelte';
2 | import basicRaw from './basic.svelte?raw';
3 | import Loop from './loop.svelte';
4 | import loopRaw from './loop.svelte?raw';
5 |
6 | const examples = {
7 | basic: {
8 | code: basicRaw,
9 | Component: Basic
10 | },
11 | loop: {
12 | code: loopRaw,
13 | Component: Loop
14 | }
15 | };
16 |
17 | export { examples };
18 |
--------------------------------------------------------------------------------
/src/routes/components/theme-selector/+page.svelte:
--------------------------------------------------------------------------------
1 |
7 |
8 | Basic
9 |
10 |
11 |
12 |
13 | Ghost
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/routes/components/theme-selector/basic.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/routes/components/theme-selector/examples.ts:
--------------------------------------------------------------------------------
1 | import Basic from './basic.svelte';
2 | import basicRaw from './basic.svelte?raw';
3 | import Variants from './variants.svelte';
4 | import variantsRaw from './variants.svelte?raw';
5 |
6 | const examples = {
7 | basic: {
8 | code: basicRaw,
9 | Component: Basic
10 | },
11 | variants: {
12 | code: variantsRaw,
13 | Component: Variants
14 | }
15 | };
16 |
17 | export { examples };
18 |
--------------------------------------------------------------------------------
/src/routes/components/theme-selector/variants.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/routes/components/toc/+page.svelte:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
12 |
13 | Usage
14 |
15 |
18 | import * as Toc from '$lib/components/ui/toc';
19 | \<\/script\>
20 |
21 | `}
22 | />
23 |
24 | Generate the table of contents with UseToc
25 |
26 |
29 | import * as Toc from '$lib/components/ui/toc';
30 |
31 | const toc = new UseToc();
32 | \<\/script\>
33 |
34 |
35 |
36 |
37 | `}
38 | />
39 |
40 |
--------------------------------------------------------------------------------
/src/routes/components/toc/basic.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/routes/components/toc/examples.ts:
--------------------------------------------------------------------------------
1 | import Basic from './basic.svelte';
2 | import basicRaw from './basic.svelte?raw';
3 |
4 | const examples = {
5 | basic: {
6 | code: basicRaw,
7 | Component: Basic
8 | }
9 | };
10 |
11 | export { examples };
12 |
--------------------------------------------------------------------------------
/src/routes/components/toc/toc.ts:
--------------------------------------------------------------------------------
1 | export const toc = [
2 | {
3 | kind: 'h2',
4 | id: 'cli',
5 | level: 2,
6 | label: 'CLI',
7 | active: false,
8 | children: [
9 | {
10 | kind: 'h3',
11 | id: 'cli-installation',
12 | level: 3,
13 | label: 'Installation',
14 | active: false,
15 | children: []
16 | }
17 | ]
18 | },
19 | {
20 | kind: 'h2',
21 | id: 'usage',
22 | level: 2,
23 | label: 'Usage',
24 | active: false,
25 | children: [
26 | {
27 | kind: 'h3',
28 | id: 'usage-components',
29 | level: 3,
30 | label: 'Components',
31 | active: false,
32 | children: []
33 | },
34 | {
35 | kind: 'h3',
36 | id: 'hooks',
37 | level: 3,
38 | label: 'Hooks',
39 | active: false,
40 | children: []
41 | }
42 | ]
43 | }
44 | ];
45 |
--------------------------------------------------------------------------------
/src/routes/components/tree-view/+page.svelte:
--------------------------------------------------------------------------------
1 |
8 |
9 | Basic
10 |
11 |
12 |
13 |
14 | Custom Icons
15 |
16 |
17 |
18 |
19 | If you are using custom icons in a project we recommend you wrap the folder/file components with
20 | the custom icons:
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/routes/components/tree-view/basic.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/routes/components/tree-view/examples.ts:
--------------------------------------------------------------------------------
1 | import Basic from './basic.svelte';
2 | import basicRaw from './basic.svelte?raw';
3 | import CustomIcons from './custom-icons.svelte';
4 | import customIconsRaw from './custom-icons.svelte?raw';
5 | import treeViewFileCustomRaw from './tree-view-file-custom.svelte?raw';
6 |
7 | const examples = {
8 | basic: {
9 | code: basicRaw,
10 | Component: Basic
11 | },
12 | customIcons: {
13 | code: customIconsRaw,
14 | Component: CustomIcons
15 | },
16 | customFileComponentCode: treeViewFileCustomRaw
17 | };
18 |
19 | export { examples };
20 |
--------------------------------------------------------------------------------
/src/routes/components/tree-view/tree-view-file-custom.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 | {#snippet icon({ name })}
14 | {#if name.endsWith('.css')}
15 |
16 | {:else if name.endsWith('.svelte')}
17 |
18 | {:else if name.endsWith('.ts')}
19 |
20 | {/if}
21 | {/snippet}
22 |
23 |
--------------------------------------------------------------------------------
/src/routes/components/window/+page.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/routes/components/window/basic.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 | # Window
7 | An awesome styled window component.
8 |
9 |
--------------------------------------------------------------------------------
/src/routes/components/window/examples.ts:
--------------------------------------------------------------------------------
1 | import Basic from './basic.svelte';
2 | import basicRaw from './basic.svelte?raw';
3 |
4 | const examples = {
5 | basic: {
6 | code: basicRaw,
7 | Component: Basic
8 | }
9 | };
10 |
11 | export { examples };
12 |
--------------------------------------------------------------------------------
/src/routes/docs/using-extras/+page.server.ts:
--------------------------------------------------------------------------------
1 | import { redirect } from '@sveltejs/kit';
2 |
3 | // just in case anyone linked to the old path
4 |
5 | export function load() {
6 | throw redirect(307, '/docs/installation');
7 | }
8 |
--------------------------------------------------------------------------------
/src/routes/docs/using-extras/+page.svelte:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ieedan/shadcn-svelte-extras/fd06d9df74e6a1a25ff1ef00b17f5dd9cf1b92fd/src/routes/docs/using-extras/+page.svelte
--------------------------------------------------------------------------------
/src/routes/hooks/use-auto-scroll/+page.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 | Usage
9 | Create a container that automatically scrolls to the bottom.
10 |
14 | import { UseAutoScroll } from '$lib/hooks/use-auto-scroll.svelte';
15 |
16 | let { children } = $props();
17 |
18 | const autoScroll = new UseAutoScroll();
19 | \<\/script\>
20 |
21 |
22 |
23 | {@render children?.()}
24 |
25 | {#if !autoScroll.isAtBottom}
26 |
autoScroll.scrollToBottom()}>
27 | Scroll To Bottom
28 |
29 | {/if}
30 |
`}
31 | />
32 |
--------------------------------------------------------------------------------
/src/routes/hooks/use-promise/basic.svelte:
--------------------------------------------------------------------------------
1 |
24 |
25 |
31 |
--------------------------------------------------------------------------------
/src/routes/hooks/use-promise/examples.ts:
--------------------------------------------------------------------------------
1 | import Basic from './basic.svelte';
2 | import basicRaw from './basic.svelte?raw';
3 |
4 | const examples = {
5 | basic: {
6 | code: basicRaw,
7 | Component: Basic
8 | }
9 | };
10 |
11 | export { examples };
12 |
--------------------------------------------------------------------------------
/src/routes/hooks/use-toc/+page.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 | Usage
9 | Generate a table of contents using the content of the page.
10 |
14 | const toc = new UseToc();
15 | \<\/script\>
16 |
17 |
18 |
Installation
19 | CLI
20 | Manual
21 | Usage
22 | `}
23 | />
24 |
--------------------------------------------------------------------------------
/static/dark.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/static/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ieedan/shadcn-svelte-extras/fd06d9df74e6a1a25ff1ef00b17f5dd9cf1b92fd/static/favicon.png
--------------------------------------------------------------------------------
/static/favicon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/static/light.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/static/og.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ieedan/shadcn-svelte-extras/fd06d9df74e6a1a25ff1ef00b17f5dd9cf1b92fd/static/og.png
--------------------------------------------------------------------------------
/svelte.config.js:
--------------------------------------------------------------------------------
1 | import adapter from '@sveltejs/adapter-vercel';
2 | import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
3 |
4 | /** @type {import('@sveltejs/kit').Config} */
5 | const config = {
6 | // Consult https://svelte.dev/docs/kit/integrations
7 | // for more information about preprocessors
8 | preprocess: vitePreprocess(),
9 |
10 | kit: {
11 | adapter: adapter()
12 | }
13 | };
14 |
15 | export default config;
16 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./.svelte-kit/tsconfig.json",
3 | "compilerOptions": {
4 | "allowJs": true,
5 | "checkJs": true,
6 | "esModuleInterop": true,
7 | "forceConsistentCasingInFileNames": true,
8 | "resolveJsonModule": true,
9 | "skipLibCheck": true,
10 | "sourceMap": true,
11 | "strict": true,
12 | "moduleResolution": "bundler"
13 | },
14 | "exclude": ["src/lib/paraglide/**"]
15 | // Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias
16 | // except $lib which is handled by https://svelte.dev/docs/kit/configuration#files
17 | //
18 | // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
19 | // from the referenced tsconfig.json - TypeScript does not merge them in
20 | }
21 |
--------------------------------------------------------------------------------
/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { paraglideVitePlugin } from '@inlang/paraglide-js';
2 | import { sveltekit } from '@sveltejs/kit/vite';
3 | import { defineConfig } from 'vite';
4 | import tailwindcss from '@tailwindcss/vite';
5 |
6 | export default defineConfig({
7 | plugins: [
8 | tailwindcss(),
9 | paraglideVitePlugin({
10 | project: './project.inlang',
11 | outdir: './src/lib/paraglide',
12 | strategy: ['url', 'cookie', 'baseLocale'],
13 | disableAsyncLocalStorage: true
14 | }),
15 | sveltekit()
16 | ]
17 | });
18 |
--------------------------------------------------------------------------------