├── .eslintignore ├── .eslintrc ├── .gitattributes ├── .github ├── .prettierrc └── workflows │ ├── ci.yml │ ├── lockfile.yml │ └── release.yml ├── .gitignore ├── .mergify.yml ├── .npmignore ├── .prettierignore ├── .prettierrc ├── .storybook ├── main.ts └── preview.ts ├── .vscode └── settings.json ├── CHANGELOG.md ├── LICENSE ├── README.md ├── cli ├── .eslintrc ├── build-icons │ ├── index.ts │ ├── marketing-icons.ts │ └── normal-icons.ts ├── create-new-component │ ├── index.ts │ └── templates │ │ ├── component-template.stories.svelte │ │ ├── component-template.svelte │ │ └── component-template.test.ts └── generate-docs │ ├── colors.ts │ ├── icons.ts │ ├── index.ts │ └── templates │ ├── colors.stories.mdx │ └── icons.stories.mdx ├── cypress.json ├── cypress ├── fixtures │ └── example.json └── support │ ├── commands-storybook.ts │ └── index.ts ├── package.json ├── pnpm-lock.yaml ├── postcss.config.cjs ├── release.config.cjs ├── renovate.json ├── src ├── components │ ├── accordion │ │ ├── _empty-component.svelte │ │ ├── accordion-group │ │ │ ├── accordion-group.stories.svelte │ │ │ ├── accordion-group.svelte │ │ │ ├── accordion-group.test.ts │ │ │ └── index.d.ts │ │ ├── accordion.stories.svelte │ │ ├── accordion.svelte │ │ └── accordion.test.ts │ ├── bottom-nav │ │ ├── bottom-nav-item │ │ │ ├── bottom-nav-item.stories.svelte │ │ │ ├── bottom-nav-item.svelte │ │ │ ├── bottom-nav-item.test.ts │ │ │ └── index.d.ts │ │ ├── bottom-nav.stories.svelte │ │ ├── bottom-nav.svelte │ │ └── bottom-nav.test.ts │ ├── empty-state │ │ ├── empty-state.stories.svelte │ │ ├── empty-state.svelte │ │ └── empty-state.test.ts │ ├── entity │ │ ├── entity-field │ │ │ ├── entity-field.stories.svelte │ │ │ └── entity-field.svelte │ │ ├── entity.stories.svelte │ │ ├── entity.svelte │ │ └── entity.test.ts │ ├── footer │ │ ├── footer-column │ │ │ ├── footer-column.stories.svelte │ │ │ └── footer-column.svelte │ │ ├── footer-group │ │ │ ├── footer-group.stories.svelte │ │ │ ├── footer-group.svelte │ │ │ └── footer-group.test.ts │ │ ├── footer-link │ │ │ ├── footer-link.stories.svelte │ │ │ └── footer-link.svelte │ │ ├── footer-social-link-wrapper │ │ │ ├── footer-social-link-wrapper.stories.svelte │ │ │ └── footer-social-link-wrapper.svelte │ │ ├── footer-social-link │ │ │ ├── footer-social-link.stories.svelte │ │ │ └── footer-social-link.svelte │ │ ├── footer.stories.svelte │ │ ├── footer.svelte │ │ └── footer.test.ts │ ├── header │ │ ├── header-brand │ │ │ ├── header-brand.stories.svelte │ │ │ ├── header-brand.svelte │ │ │ └── header-brand.test.ts │ │ ├── header-dropdown │ │ │ ├── header-dropdown.stories.svelte │ │ │ ├── header-dropdown.svelte │ │ │ └── header-dropdown.test.ts │ │ ├── header-item-wrapper │ │ │ ├── header-item-wrapper.stories.svelte │ │ │ ├── header-item-wrapper.svelte │ │ │ ├── header-item-wrapper.test.ts │ │ │ └── index.d.ts │ │ ├── header-link │ │ │ ├── header-link.stories.svelte │ │ │ ├── header-link.svelte │ │ │ └── header-link.test.ts │ │ ├── header-mobile-group │ │ │ ├── header-mobile-group.stories.svelte │ │ │ ├── header-mobile-group.svelte │ │ │ └── header-mobile-group.test.ts │ │ ├── header-mobile-item-wrapper │ │ │ ├── header-mobile-item-wrapper.stories.svelte │ │ │ ├── header-mobile-item-wrapper.svelte │ │ │ └── header-mobile-item-wrapper.test.ts │ │ ├── header-mobile-link │ │ │ ├── header-mobile-link.stories.svelte │ │ │ ├── header-mobile-link.svelte │ │ │ └── header-mobile-link.test.ts │ │ ├── header-mobile-subgroup │ │ │ ├── header-mobile-subgroup.stories.svelte │ │ │ ├── header-mobile-subgroup.svelte │ │ │ └── header-mobile-subgroup.test.ts │ │ ├── header.stories.svelte │ │ ├── header.svelte │ │ ├── header.test.ts │ │ ├── index.d.ts │ │ └── subheader │ │ │ ├── index.d.ts │ │ │ ├── subheader.stories.svelte │ │ │ ├── subheader.svelte │ │ │ └── subheader.test.ts │ ├── list │ │ ├── index.d.ts │ │ ├── list-divider │ │ │ ├── list-divider.stories.svelte │ │ │ ├── list-divider.svelte │ │ │ └── list-divider.test.ts │ │ ├── list-item │ │ │ ├── index.d.ts │ │ │ ├── list-item.stories.svelte │ │ │ ├── list-item.svelte │ │ │ └── list-item.test.ts │ │ ├── list.stories.svelte │ │ ├── list.svelte │ │ └── list.test.ts │ ├── media-scroller │ │ ├── media-scroller.stories.svelte │ │ ├── media-scroller.svelte │ │ └── media-scroller.test.ts │ ├── menu │ │ ├── menu.stories.svelte │ │ ├── menu.svelte │ │ └── menu.test.ts │ ├── modal │ │ ├── index.d.ts │ │ ├── modal-form │ │ │ ├── modal-form.stories.svelte │ │ │ ├── modal-form.svelte │ │ │ └── modal-form.test.ts │ │ ├── modal-success │ │ │ ├── modal-success.stories.svelte │ │ │ ├── modal-success.svelte │ │ │ └── modal-success.test.ts │ │ ├── modal.stories.svelte │ │ ├── modal.svelte │ │ └── modal.test.ts │ ├── popover │ │ ├── index.d.ts │ │ ├── popover.stories.svelte │ │ ├── popover.svelte │ │ └── popover.test.ts │ ├── table-of-contents │ │ ├── index.d.ts │ │ ├── table-of-contents.stories.svelte │ │ ├── table-of-contents.svelte │ │ └── table-of-contents.test.ts │ ├── tabs │ │ ├── tab-item │ │ │ ├── tab-item.stories.svelte │ │ │ ├── tab-item.svelte │ │ │ └── tab-item.test.ts │ │ ├── tabs.stories.svelte │ │ ├── tabs.svelte │ │ └── tabs.test.ts │ ├── toast │ │ ├── _toast-item.svelte │ │ ├── index.ts │ │ ├── toast.stories.svelte │ │ ├── toast.svelte │ │ └── toast.test.ts │ ├── tooltip │ │ ├── tooltip.stories.svelte │ │ ├── tooltip.svelte │ │ └── tooltip.test.ts │ └── youtube-video │ │ ├── youtube-video.stories.svelte │ │ ├── youtube-video.svelte │ │ └── youtube-video.test.ts ├── configs │ └── transitions.ts ├── elements │ ├── badge │ │ ├── badge.stories.svelte │ │ └── badge.svelte │ ├── button │ │ ├── button.stories.svelte │ │ ├── button.svelte │ │ └── button.test.ts │ ├── dark-mode-select │ │ ├── dark-mode-select.stories.svelte │ │ └── dark-mode-select.svelte │ ├── error │ │ ├── error.stories.svelte │ │ ├── error.svelte │ │ └── error.test.ts │ ├── icon │ │ ├── academic-cap.svelte │ │ ├── activity.svelte │ │ ├── airplay.svelte │ │ ├── alert-circle.svelte │ │ ├── alert-octagon.svelte │ │ ├── alert-triangle.svelte │ │ ├── align-center.svelte │ │ ├── align-justify.svelte │ │ ├── align-left.svelte │ │ ├── align-right.svelte │ │ ├── anchor.svelte │ │ ├── aperture.svelte │ │ ├── apple.svelte │ │ ├── archive.svelte │ │ ├── arrow-down-circle.svelte │ │ ├── arrow-down-left.svelte │ │ ├── arrow-down-right.svelte │ │ ├── arrow-down.svelte │ │ ├── arrow-left-circle.svelte │ │ ├── arrow-left.svelte │ │ ├── arrow-right-circle.svelte │ │ ├── arrow-right.svelte │ │ ├── arrow-up-circle.svelte │ │ ├── arrow-up-left.svelte │ │ ├── arrow-up-right.svelte │ │ ├── arrow-up.svelte │ │ ├── at-sign.svelte │ │ ├── award.svelte │ │ ├── bar-chart-2.svelte │ │ ├── bar-chart.svelte │ │ ├── battery-charging.svelte │ │ ├── battery.svelte │ │ ├── bell-off.svelte │ │ ├── bell.svelte │ │ ├── bluetooth.svelte │ │ ├── bold.svelte │ │ ├── book-open.svelte │ │ ├── book.svelte │ │ ├── bookmark.svelte │ │ ├── box.svelte │ │ ├── briefcase.svelte │ │ ├── calendar.svelte │ │ ├── camera-off.svelte │ │ ├── camera.svelte │ │ ├── cast.svelte │ │ ├── check-circle.svelte │ │ ├── check-square.svelte │ │ ├── check.svelte │ │ ├── chevron-down.svelte │ │ ├── chevron-left.svelte │ │ ├── chevron-right.svelte │ │ ├── chevron-up.svelte │ │ ├── chevrons-down.svelte │ │ ├── chevrons-left.svelte │ │ ├── chevrons-right.svelte │ │ ├── chevrons-up.svelte │ │ ├── chrome.svelte │ │ ├── circle.svelte │ │ ├── clipboard.svelte │ │ ├── clock.svelte │ │ ├── cloud-drizzle.svelte │ │ ├── cloud-lightning.svelte │ │ ├── cloud-off.svelte │ │ ├── cloud-rain.svelte │ │ ├── cloud-snow.svelte │ │ ├── cloud.svelte │ │ ├── code.svelte │ │ ├── codepen.svelte │ │ ├── codesandbox.svelte │ │ ├── coffee.svelte │ │ ├── columns.svelte │ │ ├── command.svelte │ │ ├── compass.svelte │ │ ├── copy.svelte │ │ ├── corner-down-left.svelte │ │ ├── corner-down-right.svelte │ │ ├── corner-left-down.svelte │ │ ├── corner-left-up.svelte │ │ ├── corner-right-down.svelte │ │ ├── corner-right-up.svelte │ │ ├── corner-up-left.svelte │ │ ├── corner-up-right.svelte │ │ ├── cpu.svelte │ │ ├── credit-card.svelte │ │ ├── crop.svelte │ │ ├── crosshair.svelte │ │ ├── database.svelte │ │ ├── delete.svelte │ │ ├── disc.svelte │ │ ├── divide-circle.svelte │ │ ├── divide-square.svelte │ │ ├── divide.svelte │ │ ├── divider.svelte │ │ ├── dollar-sign.svelte │ │ ├── dot.svelte │ │ ├── download-cloud.svelte │ │ ├── download.svelte │ │ ├── dribbble.svelte │ │ ├── droplet.svelte │ │ ├── edit-2.svelte │ │ ├── edit-3.svelte │ │ ├── edit.svelte │ │ ├── external-link.svelte │ │ ├── eye-off.svelte │ │ ├── eye.svelte │ │ ├── facebook.svelte │ │ ├── fast-forward.svelte │ │ ├── feather.svelte │ │ ├── figma.svelte │ │ ├── file-minus.svelte │ │ ├── file-plus.svelte │ │ ├── file-text.svelte │ │ ├── file.svelte │ │ ├── film.svelte │ │ ├── filter.svelte │ │ ├── flag.svelte │ │ ├── folder-minus.svelte │ │ ├── folder-plus.svelte │ │ ├── folder.svelte │ │ ├── framer.svelte │ │ ├── frown.svelte │ │ ├── gift.svelte │ │ ├── git-branch.svelte │ │ ├── git-commit.svelte │ │ ├── git-merge.svelte │ │ ├── git-pull-request.svelte │ │ ├── github.svelte │ │ ├── gitlab.svelte │ │ ├── globe.svelte │ │ ├── google-maps.svelte │ │ ├── google.svelte │ │ ├── grid.svelte │ │ ├── hard-drive.svelte │ │ ├── hash.svelte │ │ ├── heading-1.svelte │ │ ├── heading-2.svelte │ │ ├── headphones.svelte │ │ ├── heart.svelte │ │ ├── help-circle.svelte │ │ ├── hexagon.svelte │ │ ├── home.svelte │ │ ├── identification.svelte │ │ ├── image.svelte │ │ ├── inbox.svelte │ │ ├── info.svelte │ │ ├── instagram.svelte │ │ ├── italic.svelte │ │ ├── key.svelte │ │ ├── layers.svelte │ │ ├── layout.svelte │ │ ├── life-buoy.svelte │ │ ├── link-2.svelte │ │ ├── link.svelte │ │ ├── linkedin.svelte │ │ ├── list-numbered.svelte │ │ ├── list.svelte │ │ ├── loader.svelte │ │ ├── lock.svelte │ │ ├── log-in.svelte │ │ ├── log-out.svelte │ │ ├── mail.svelte │ │ ├── map-pin.svelte │ │ ├── map.svelte │ │ ├── maximize-2.svelte │ │ ├── maximize.svelte │ │ ├── medium.svelte │ │ ├── meh.svelte │ │ ├── menu.svelte │ │ ├── message-circle.svelte │ │ ├── message-square.svelte │ │ ├── mic-off.svelte │ │ ├── mic.svelte │ │ ├── minimize-2.svelte │ │ ├── minimize.svelte │ │ ├── minus-circle.svelte │ │ ├── minus-square.svelte │ │ ├── minus.svelte │ │ ├── monitor.svelte │ │ ├── moon.svelte │ │ ├── more-horizontal.svelte │ │ ├── more-vertical.svelte │ │ ├── mouse-pointer.svelte │ │ ├── move.svelte │ │ ├── music.svelte │ │ ├── navigation-2.svelte │ │ ├── navigation.svelte │ │ ├── octagon.svelte │ │ ├── office-building.svelte │ │ ├── package.svelte │ │ ├── paperclip.svelte │ │ ├── patreon.svelte │ │ ├── pause-circle.svelte │ │ ├── pause.svelte │ │ ├── paypal.svelte │ │ ├── pen-tool.svelte │ │ ├── percent.svelte │ │ ├── phone-call.svelte │ │ ├── phone-forwarded.svelte │ │ ├── phone-incoming.svelte │ │ ├── phone-missed.svelte │ │ ├── phone-off.svelte │ │ ├── phone-outgoing.svelte │ │ ├── phone.svelte │ │ ├── pie-chart.svelte │ │ ├── play-circle.svelte │ │ ├── play.svelte │ │ ├── plus-circle.svelte │ │ ├── plus-square.svelte │ │ ├── plus.svelte │ │ ├── pocket.svelte │ │ ├── power.svelte │ │ ├── printer.svelte │ │ ├── quote.svelte │ │ ├── radio.svelte │ │ ├── refresh-ccw.svelte │ │ ├── refresh-cw.svelte │ │ ├── repeat.svelte │ │ ├── rewind.svelte │ │ ├── rotate-ccw.svelte │ │ ├── rotate-cw.svelte │ │ ├── rss.svelte │ │ ├── save.svelte │ │ ├── scissors.svelte │ │ ├── search.svelte │ │ ├── send.svelte │ │ ├── server.svelte │ │ ├── settings.svelte │ │ ├── share-2.svelte │ │ ├── share.svelte │ │ ├── shield-off.svelte │ │ ├── shield.svelte │ │ ├── shopping-bag.svelte │ │ ├── shopping-cart.svelte │ │ ├── shuffle.svelte │ │ ├── sidebar.svelte │ │ ├── skip-back.svelte │ │ ├── skip-forward.svelte │ │ ├── slack.svelte │ │ ├── slash.svelte │ │ ├── sliders.svelte │ │ ├── smartphone.svelte │ │ ├── smile.svelte │ │ ├── soundcloud.svelte │ │ ├── speaker.svelte │ │ ├── spotify.svelte │ │ ├── square.svelte │ │ ├── star.svelte │ │ ├── stop-circle.svelte │ │ ├── storybook │ │ │ ├── icon.stories.svelte │ │ │ └── icon.svelte │ │ ├── sun.svelte │ │ ├── sunrise.svelte │ │ ├── sunset.svelte │ │ ├── tablet.svelte │ │ ├── tag.svelte │ │ ├── target.svelte │ │ ├── terminal.svelte │ │ ├── thermometer.svelte │ │ ├── thumbs-down.svelte │ │ ├── thumbs-up.svelte │ │ ├── toggle-left.svelte │ │ ├── toggle-right.svelte │ │ ├── tool.svelte │ │ ├── trash-2.svelte │ │ ├── trash.svelte │ │ ├── trello.svelte │ │ ├── trending-down.svelte │ │ ├── trending-up.svelte │ │ ├── triangle.svelte │ │ ├── truck.svelte │ │ ├── tv.svelte │ │ ├── twitch.svelte │ │ ├── twitter.svelte │ │ ├── type.svelte │ │ ├── umbrella.svelte │ │ ├── underline.svelte │ │ ├── unlock.svelte │ │ ├── upload-cloud.svelte │ │ ├── upload.svelte │ │ ├── user-check.svelte │ │ ├── user-group.svelte │ │ ├── user-minus.svelte │ │ ├── user-plus.svelte │ │ ├── user-x.svelte │ │ ├── user.svelte │ │ ├── users.svelte │ │ ├── video-off.svelte │ │ ├── video.svelte │ │ ├── voicemail.svelte │ │ ├── volume-1.svelte │ │ ├── volume-2.svelte │ │ ├── volume-x.svelte │ │ ├── volume.svelte │ │ ├── watch.svelte │ │ ├── wifi-off.svelte │ │ ├── wifi.svelte │ │ ├── wind.svelte │ │ ├── windows.svelte │ │ ├── x-circle.svelte │ │ ├── x-octagon.svelte │ │ ├── x-square.svelte │ │ ├── x.svelte │ │ ├── youtube.svelte │ │ ├── zap-off.svelte │ │ ├── zap.svelte │ │ ├── zoom-in.svelte │ │ └── zoom-out.svelte │ ├── loading-dots │ │ ├── loading-dots.stories.svelte │ │ └── loading-dots.svelte │ ├── loading-progress-indicator │ │ ├── indicator.svelte │ │ ├── loading-progress-indicator.stories.svelte │ │ └── loading-progress-indicator.svelte │ ├── loading-section │ │ ├── loading-section.stories.svelte │ │ └── loading-section.svelte │ ├── loading-spinner │ │ ├── loading-spinner.stories.svelte │ │ └── loading-spinner.svelte │ ├── marketing-icon │ │ ├── analytics.svelte │ │ ├── at.svelte │ │ ├── book-user.svelte │ │ ├── bookmark.svelte │ │ ├── bug.svelte │ │ ├── clipboard.svelte │ │ ├── computer-speaker.svelte │ │ ├── download.svelte │ │ ├── envelope-square.svelte │ │ ├── file-code.svelte │ │ ├── file-music.svelte │ │ ├── files-text.svelte │ │ ├── globe.svelte │ │ ├── hands-helping.svelte │ │ ├── heart-circle.svelte │ │ ├── laptop-code.svelte │ │ ├── lightbulb-on.svelte │ │ ├── storybook │ │ │ ├── marketing-icon.stories.svelte │ │ │ ├── marketing-icon.svelte │ │ │ └── marketing-icon.test.ts │ │ ├── tv-music.svelte │ │ └── user-edit.svelte │ ├── note │ │ ├── note.stories.svelte │ │ ├── note.svelte │ │ └── note.test.ts │ ├── progress-bar │ │ ├── progress-bar.stories.svelte │ │ ├── progress-bar.svelte │ │ └── progress-bar.test.ts │ └── status-dot │ │ ├── status-dot.stories.svelte │ │ └── status-dot.svelte ├── form │ ├── form-entity │ │ ├── form-entity.stories.svelte │ │ ├── form-entity.svelte │ │ ├── form-entity.test.ts │ │ └── index.d.ts │ ├── form-feedback.ts │ ├── form-sizes.ts │ ├── form │ │ ├── form.stories.svelte │ │ ├── form.svelte │ │ └── form.test.ts │ ├── index.d.ts │ ├── inputs │ │ ├── avatar-input │ │ │ ├── avatar-input.stories.svelte │ │ │ ├── avatar-input.svelte │ │ │ ├── avatar-input.test.ts │ │ │ └── index.d.ts │ │ ├── check-input │ │ │ ├── check-input.stories.svelte │ │ │ ├── check-input.svelte │ │ │ ├── check-input.test.ts │ │ │ └── index.d.ts │ │ ├── date-input │ │ │ ├── date-input.stories.svelte │ │ │ ├── date-input.svelte │ │ │ └── date-input.test.ts │ │ ├── default-text-inputs.test.ts │ │ ├── dollar-input │ │ │ ├── dollar-input.stories.svelte │ │ │ ├── dollar-input.svelte │ │ │ └── dollar-input.test.ts │ │ ├── email-input │ │ │ ├── email-input.stories.svelte │ │ │ ├── email-input.svelte │ │ │ └── email-input.test.ts │ │ ├── facebook-page-input │ │ │ ├── facebook-page-input.stories.svelte │ │ │ ├── facebook-page-input.svelte │ │ │ └── facebook-page-input.test.ts │ │ ├── file-input │ │ │ ├── file-input.stories.svelte │ │ │ ├── file-input.svelte │ │ │ └── file-input.test.ts │ │ ├── image-input │ │ │ ├── image-input.stories.svelte │ │ │ ├── image-input.svelte │ │ │ └── image-input.test.ts │ │ ├── linkedin-input │ │ │ ├── linkedin-input.stories.svelte │ │ │ ├── linkedin-input.svelte │ │ │ └── linkedin-input.test.ts │ │ ├── name-input │ │ │ ├── name-input.stories.svelte │ │ │ ├── name-input.svelte │ │ │ └── name-input.test.ts │ │ ├── new-password-input │ │ │ ├── new-password-input.stories.svelte │ │ │ ├── new-password-input.svelte │ │ │ └── new-password-input.test.ts │ │ ├── number-input │ │ │ ├── number-input.stories.svelte │ │ │ ├── number-input.svelte │ │ │ └── number-input.test.ts │ │ ├── password-input │ │ │ ├── password-input.stories.svelte │ │ │ ├── password-input.svelte │ │ │ └── password-input.test.ts │ │ ├── rich-text-input │ │ │ ├── _build-extensions.ts │ │ │ ├── _image.ts │ │ │ ├── rich-text-input.stories.svelte │ │ │ ├── rich-text-input.svelte │ │ │ └── rich-text-input.test.ts │ │ ├── search-input │ │ │ ├── _search-input-refresh.svelte │ │ │ ├── search-input.stories.svelte │ │ │ └── search-input.svelte │ │ ├── select │ │ │ ├── select.stories.svelte │ │ │ └── select.svelte │ │ ├── text-input │ │ │ ├── _input-feedback-section.svelte │ │ │ ├── index.d.ts │ │ │ ├── text-input-affix.svelte │ │ │ ├── text-input.stories.svelte │ │ │ ├── text-input.svelte │ │ │ └── text-input.test.ts │ │ ├── twitter-profile-input │ │ │ ├── twitter-profile-input.stories.svelte │ │ │ ├── twitter-profile-input.svelte │ │ │ └── twitter-profile-input.test.ts │ │ ├── url-input │ │ │ ├── url-input.stories.svelte │ │ │ ├── url-input.svelte │ │ │ └── url-input.test.ts │ │ ├── youtube-channel-input │ │ │ ├── youtube-channel-input.stories.svelte │ │ │ ├── youtube-channel-input.svelte │ │ │ └── youtube-channel-input.test.ts │ │ └── youtube-video-input │ │ │ ├── youtube-video-input.stories.svelte │ │ │ ├── youtube-video-input.svelte │ │ │ └── youtube-video-input.test.ts │ ├── label │ │ ├── label.stories.svelte │ │ ├── label.svelte │ │ └── label.test.ts │ └── submit │ │ ├── submit.stories.svelte │ │ ├── submit.svelte │ │ └── submit.test.ts ├── layouts │ ├── auth │ │ ├── auth.stories.svelte │ │ ├── auth.svelte │ │ ├── auth.test.ts │ │ ├── forgot-password │ │ │ ├── forgot-password.stories.svelte │ │ │ ├── forgot-password.svelte │ │ │ └── forgot-password.test.ts │ │ ├── oauth │ │ │ ├── index.d.ts │ │ │ ├── oauth.stories.svelte │ │ │ ├── oauth.svelte │ │ │ └── oauth.test.ts │ │ ├── reset-password │ │ │ ├── reset-password.stories.svelte │ │ │ ├── reset-password.svelte │ │ │ └── reset-password.test.ts │ │ ├── sign-in │ │ │ ├── sign-in.stories.svelte │ │ │ ├── sign-in.svelte │ │ │ └── sign-in.test.ts │ │ └── sign-up │ │ │ ├── sign-up.stories.svelte │ │ │ ├── sign-up.svelte │ │ │ └── sign-up.test.ts │ ├── changelog │ │ ├── changelog-item-page │ │ │ ├── changelog-item-page.stories.svelte │ │ │ ├── changelog-item-page.svelte │ │ │ └── changelog-item-page.test.ts │ │ ├── changelog.stories.svelte │ │ ├── changelog.svelte │ │ ├── changelog.test.ts │ │ └── index.d.ts │ ├── dashboard │ │ └── dashboard-sidebar │ │ │ ├── dashboard-sidebar.stories.svelte │ │ │ ├── dashboard-sidebar.svelte │ │ │ ├── dashboard-sidebar.test.ts │ │ │ └── index.d.ts │ ├── http-404 │ │ ├── http-404.stories.svelte │ │ └── http-404.svelte │ └── http-500 │ │ ├── http-500.stories.svelte │ │ └── http-500.svelte ├── style-guide │ ├── colors.stories.mdx │ └── icons.stories.mdx ├── svg-marketing │ ├── analytics.svg │ ├── at.svg │ ├── book-user.svg │ ├── bookmark.svg │ ├── bug.svg │ ├── clipboard.svg │ ├── computer-speaker.svg │ ├── download.svg │ ├── envelope-square.svg │ ├── file-code.svg │ ├── file-music.svg │ ├── files-text.svg │ ├── globe.svg │ ├── hands-helping.svg │ ├── heart-circle.svg │ ├── laptop-code.svg │ ├── lightbulb-on.svg │ ├── tv-music.svg │ └── user-edit.svg ├── svg │ ├── README.md │ ├── academic-cap.svg │ ├── apple.svg │ ├── divider.svg │ ├── dot.svg │ ├── facebook.svg │ ├── github.svg │ ├── google-maps.svg │ ├── google.svg │ ├── heading-1.svg │ ├── heading-2.svg │ ├── identification.svg │ ├── linkedin.svg │ ├── list-numbered.svg │ ├── medium.svg │ ├── office-building.svg │ ├── patreon.svg │ ├── paypal.svg │ ├── quote.svg │ ├── rss.svg │ ├── search.svg │ ├── soundcloud.svg │ ├── spotify.svg │ ├── twitter.svg │ ├── user-group.svg │ ├── user.svg │ ├── windows.svg │ └── youtube.svg ├── typography │ └── markdown │ │ ├── markdown.stories.svelte │ │ └── markdown.svelte └── utilities │ ├── container │ ├── container.stories.svelte │ └── container.svelte │ ├── portal │ ├── portal.stories.svelte │ └── portal.svelte │ ├── seo │ ├── index.d.ts │ ├── seo.stories.svelte │ ├── seo.svelte │ └── seo.test.ts │ └── spacer │ ├── spacer.stories.svelte │ └── spacer.svelte ├── svelte.config.cjs ├── tailwind.config.cjs ├── tsconfig.json ├── types.d.ts └── vercel.json /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .vscode 3 | 4 | *.d.ts 5 | *.config.js 6 | cli/dist 7 | src/style-guide/colors.stories.mdx 8 | src/style-guide/icons.stories.mdx 9 | src/elements/icon/*.svelte 10 | src/elements/marketing-icon/*.svelte 11 | 12 | src/form/inputs/rich-text-input/rich-text-input.stories.svelte -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["@nick-mazuk/eslint-config/svelte", "@nick-mazuk/eslint-config/+cypress"], 3 | "overrides": [ 4 | { 5 | "files": ["*.stories.svelte"], 6 | "rules": { 7 | "no-alert": "off" 8 | } 9 | } 10 | ], 11 | "globals": { 12 | "svelte": "readonly", 13 | "NodeJS": "readonly" 14 | }, 15 | "rules": { 16 | "@typescript-eslint/prefer-nullish-coalescing": "warn" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.github/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 2 3 | } 4 | -------------------------------------------------------------------------------- /.github/workflows/lockfile.yml: -------------------------------------------------------------------------------- 1 | name: Fix lockfile 2 | 3 | on: 4 | push: 5 | branches: 6 | - "renovate**" 7 | 8 | jobs: 9 | update-lockfile: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v2 13 | - uses: actions/setup-node@v2.2.0 14 | with: 15 | node-version: 14 16 | - run: npx pnpm i --lockfile-only 17 | - name: push lockfile to branch 18 | uses: actions-js/push@v1.2 19 | with: 20 | github_token: ${{ secrets.GITHUB_TOKEN }} 21 | branch: ${{ github.ref }} 22 | message: "build: update lockfile" 23 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | release: 10 | name: Release 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v2 14 | - uses: actions/setup-node@v2.2.0 15 | with: 16 | node-version: 14 17 | - name: Cache ~/.pnpm-store 18 | uses: actions/cache@main 19 | with: 20 | path: ~/.pnpm-store 21 | key: ${{ runner.os }}-14-${{ hashFiles('**/pnpm-lock.yaml') }} 22 | restore-keys: | 23 | ${{ runner.os }}-${{ matrix.node }} 24 | - name: Install dependencies 25 | run: npx pnpm i --frozen-lockfile=false 26 | - name: Release 27 | env: 28 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 29 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 30 | run: npx semantic-release 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist/ 4 | docs 5 | cli/dist 6 | build-storybook.log 7 | cypress/videos -------------------------------------------------------------------------------- /.mergify.yml: -------------------------------------------------------------------------------- 1 | pull_request_rules: 2 | - name: Merge my PRs 3 | conditions: 4 | - author=Nick-Mazuk 5 | - base=main 6 | - check-success=test-push (12) 7 | - check-success=test-push (14) 8 | - check-success=cypress (chrome) 9 | - check-success=Vercel 10 | actions: 11 | merge: 12 | method: merge 13 | strict: smart+fasttrack 14 | - name: Merge renovate 15 | conditions: 16 | - author=renovate-bot 17 | - base=main 18 | - check-success=test-push (12) 19 | - check-success=test-push (14) 20 | - check-success=cypress (chrome) 21 | - check-success=Vercel 22 | actions: 23 | merge: 24 | method: merge 25 | strict: smart+fasttrack 26 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | src/**/*.test.ts 2 | src/**/*.stories.svelte 3 | src/svg 4 | src/svg-marketing 5 | src/style-guide 6 | build-storybook.log -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | pnpm-lock.yaml 2 | .jest-test-results.json 3 | src/elements/icon/*.svelte 4 | src/elements/marketing-icon/*.svelte 5 | src/style-guide/colors.stories.mdx 6 | src/style-guide/icons.stories.mdx 7 | cli/dist 8 | CHANGELOG.md -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "printWidth": 100, 4 | "tabWidth": 4, 5 | "useTabs": false, 6 | "semi": false, 7 | "quoteProps": "as-needed", 8 | "jsxSingleQuote": true, 9 | "trailingComma": "es5", 10 | "bracketSpacing": true, 11 | "arrowParens": "always", 12 | "proseWrap": "never", 13 | "htmlWhitespaceSensitivity": "css", 14 | "endOfLine": "lf", 15 | "embeddedLanguageFormatting": "auto", 16 | "svelteStrictMode": true, 17 | "svelteAllowShorthand": true, 18 | "svelteBracketNewLine": true, 19 | "svelteIndentScriptAndStyle": true 20 | } 21 | -------------------------------------------------------------------------------- /.storybook/main.ts: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | stories: ['../src/**/*.stories.svelte', '../src/**/*.stories.mdx'], 3 | addons: [ 4 | // 'storybook-addon-turbo-build', 5 | { name: '@storybook/addon-essentials', options: { backgrounds: false, actions: true } }, 6 | '@storybook/addon-links', 7 | '@storybook/addon-a11y', 8 | '@storybook/addon-svelte-csf', 9 | 'storybook-addon-themes', 10 | { 11 | name: '@storybook/addon-postcss', 12 | options: { 13 | postcssLoaderOptions: { 14 | implementation: require('postcss'), 15 | }, 16 | }, 17 | }, 18 | 'storybook-addon-pseudo-states', 19 | 'storybook-addon-outline', 20 | ], 21 | webpackFinal: async (config) => { 22 | const svelteLoader = config.module.rules.find( 23 | (r) => r.loader && r.loader.includes('svelte-loader') 24 | ) 25 | svelteLoader.options.preprocess = require('svelte-preprocess')({ 26 | tsconfigFile: './tsconfig.json', 27 | }) 28 | return config 29 | }, 30 | } 31 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.codeActionsOnSave": { 3 | "source.fixAll.eslint": true, 4 | "source.fixAll": true 5 | }, 6 | "eslint.run": "onType", 7 | "javascript.updateImportsOnFileMove.enabled": "always", 8 | "typescript.updateImportsOnFileMove.enabled": "always", 9 | "search.exclude": { 10 | "**/node_modules": true, 11 | "**/bower_components": true 12 | }, 13 | "importCost.mediumPackageSize": 25, 14 | "importCost.smallPackageSize": 5, 15 | "importCost.timeout": 200000, 16 | "editor.formatOnPaste": true, 17 | "editor.formatOnSave": true, 18 | "editor.defaultFormatter": "esbenp.prettier-vscode", 19 | "[svelte]": { 20 | "editor.defaultFormatter": "svelte.svelte-vscode" 21 | }, 22 | "files.exclude": { 23 | "cli/dist": true 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Nick Mazuk 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## UI-Svelte 2 | 3 | A highly opinionated ui component library for Svelte. 4 | 5 | > Note, this package is still under active development and is still in beta. Expect breaking changes. 6 | 7 | Check out the Storybook docs: https://ui-svelte.vercel.app/ 8 | 9 | ## Install 10 | 11 | ``` 12 | pnpm i @nick-mazuk/ui-svelte 13 | ``` 14 | 15 | and install the needed peer dependencies. 16 | -------------------------------------------------------------------------------- /cli/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["@nick-mazuk/eslint-config/cli"] 3 | } 4 | -------------------------------------------------------------------------------- /cli/build-icons/index.ts: -------------------------------------------------------------------------------- 1 | import { buildMarketingIcons } from './marketing-icons' 2 | import { buildIcons } from './normal-icons' 3 | 4 | buildIcons() 5 | buildMarketingIcons() 6 | -------------------------------------------------------------------------------- /cli/create-new-component/templates/component-template.stories.svelte: -------------------------------------------------------------------------------- 1 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /cli/create-new-component/templates/component-template.svelte: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /cli/create-new-component/templates/component-template.test.ts: -------------------------------------------------------------------------------- 1 | context('ComponentTemplate', () => { 2 | it('renders', () => { 3 | cy.loadStory('ComponentTemplateWithCategory', 'Default') 4 | cy.checkAccessibility() 5 | }) 6 | }) 7 | 8 | export {} 9 | -------------------------------------------------------------------------------- /cli/generate-docs/index.ts: -------------------------------------------------------------------------------- 1 | import { generateColorDocs } from './colors' 2 | import { generateIconsDocs } from './icons' 3 | 4 | generateColorDocs() 5 | generateIconsDocs() 6 | -------------------------------------------------------------------------------- /cli/generate-docs/templates/colors.stories.mdx: -------------------------------------------------------------------------------- 1 | import { Meta } from '@storybook/addon-docs/blocks' 2 | 3 | 4 | 5 |
6 |

Color

7 |
8 | -------------------------------------------------------------------------------- /cli/generate-docs/templates/icons.stories.mdx: -------------------------------------------------------------------------------- 1 | import { Meta } from '@storybook/addon-docs/blocks' 2 | 3 | 4 | 5 |
6 |

Icons

7 |
8 | 9 |
10 | INSERT ICONS HERE 11 |
12 | -------------------------------------------------------------------------------- /cypress.json: -------------------------------------------------------------------------------- 1 | { 2 | "integrationFolder": "src", 3 | "testFiles": "**/*.test.ts", 4 | "baseUrl": "http://localhost:6006", 5 | "viewportWidth": 1024, 6 | "projectId": "e5fxt3" 7 | } 8 | -------------------------------------------------------------------------------- /cypress/fixtures/example.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Using fixtures to represent data", 3 | "email": "hello@cypress.io", 4 | "body": "Fixtures are a great way to mock data for responses to routes" 5 | } 6 | -------------------------------------------------------------------------------- /cypress/support/index.ts: -------------------------------------------------------------------------------- 1 | import './commands-storybook' 2 | import 'cypress-plugin-tab' 3 | import 'cypress-real-events/support' 4 | -------------------------------------------------------------------------------- /postcss.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [require('tailwindcss'), require('autoprefixer')], 3 | } 4 | -------------------------------------------------------------------------------- /release.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['@nick-mazuk/semantic-release-config'], 3 | } 4 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["config:base", ":preserveSemverRanges"], 3 | "automerge": true, 4 | "automergeType": "branch", 5 | "lockFileMaintenance": { 6 | "enabled": true 7 | }, 8 | "packageRules": [ 9 | { 10 | "matchPackagePatterns": ["^@nick-mazuk"], 11 | "prPriority": 5 12 | } 13 | ], 14 | "commitMessageAction": "bump: bump" 15 | } 16 | -------------------------------------------------------------------------------- /src/components/accordion/_empty-component.svelte: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/components/accordion/accordion-group/accordion-group.svelte: -------------------------------------------------------------------------------- 1 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/components/accordion/accordion-group/accordion-group.test.ts: -------------------------------------------------------------------------------- 1 | context('AccordionGroup', () => { 2 | it('renders', () => { 3 | cy.loadStory('Components/Accordion/AccordionGroup', 'Default') 4 | cy.checkAccessibility() 5 | }) 6 | }) 7 | 8 | export {} 9 | -------------------------------------------------------------------------------- /src/components/accordion/accordion-group/index.d.ts: -------------------------------------------------------------------------------- 1 | import type { Writable } from 'svelte/store' 2 | 3 | export type AccordionGroupContext = 4 | | { 5 | openedItem: Writable 6 | } 7 | | undefined 8 | -------------------------------------------------------------------------------- /src/components/accordion/accordion.test.ts: -------------------------------------------------------------------------------- 1 | const content = '[data-test="accordion-content"]' 2 | 3 | context('Accordion', () => { 4 | it('renders', () => { 5 | cy.loadStory('Components/Accordion', 'Default') 6 | cy.checkAccessibility() 7 | 8 | cy.get(content).should('exist').should('not.be.visible') 9 | cy.get('summary').click() 10 | cy.get(content).should('be.visible') 11 | cy.get('summary').click() 12 | cy.get(content).should('exist').should('not.be.visible') 13 | 14 | cy.get('summary').focus() 15 | cy.realPress(' ') 16 | cy.get(content).should('be.visible') 17 | cy.realPress(' ') 18 | cy.get(content).should('exist').should('not.be.visible') 19 | }) 20 | }) 21 | 22 | export {} 23 | -------------------------------------------------------------------------------- /src/components/bottom-nav/bottom-nav-item/bottom-nav-item.stories.svelte: -------------------------------------------------------------------------------- 1 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/components/bottom-nav/bottom-nav-item/bottom-nav-item.svelte: -------------------------------------------------------------------------------- 1 | 18 | 19 | 30 | -------------------------------------------------------------------------------- /src/components/bottom-nav/bottom-nav-item/bottom-nav-item.test.ts: -------------------------------------------------------------------------------- 1 | context('BottomNavItem', () => { 2 | it('renders', () => { 3 | cy.loadStory('Components/Bottom Nav/BottomNavItem', 'Default') 4 | cy.checkAccessibility() 5 | }) 6 | }) 7 | 8 | export {} 9 | -------------------------------------------------------------------------------- /src/components/bottom-nav/bottom-nav-item/index.d.ts: -------------------------------------------------------------------------------- 1 | export type BottomNavItemVariant = 2 | | 'primary' 3 | | 'error' 4 | | 'success' 5 | | 'warning' 6 | | 'gray' 7 | | 'highlight' 8 | -------------------------------------------------------------------------------- /src/components/bottom-nav/bottom-nav.stories.svelte: -------------------------------------------------------------------------------- 1 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/components/bottom-nav/bottom-nav.svelte: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | -------------------------------------------------------------------------------- /src/components/bottom-nav/bottom-nav.test.ts: -------------------------------------------------------------------------------- 1 | context('BottomNav', () => { 2 | it('renders', () => { 3 | cy.loadStory('Components/BottomNav', 'Default') 4 | cy.checkAccessibility() 5 | }) 6 | }) 7 | 8 | export {} 9 | -------------------------------------------------------------------------------- /src/components/empty-state/empty-state.svelte: -------------------------------------------------------------------------------- 1 | 7 | 8 |
9 | {#if $$slots.image} 10 |
11 | 12 |
13 | 14 | {/if} 15 |

{title}

16 | {#if description} 17 | 18 |

19 | {description} 20 |

21 | {/if} 22 | {#if $$slots.cta} 23 | 24 |
25 | 26 |
27 | {/if} 28 |
29 | -------------------------------------------------------------------------------- /src/components/empty-state/empty-state.test.ts: -------------------------------------------------------------------------------- 1 | context('EmptyState', () => { 2 | it('renders', () => { 3 | cy.loadStory('Components/EmptyState', 'Default') 4 | cy.checkAccessibility() 5 | }) 6 | }) 7 | 8 | export {} 9 | -------------------------------------------------------------------------------- /src/components/entity/entity-field/entity-field.stories.svelte: -------------------------------------------------------------------------------- 1 | 20 | 21 | 22 | 23 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/components/entity/entity-field/entity-field.svelte: -------------------------------------------------------------------------------- 1 | 5 | 6 |
11 | {#if title} 12 |

{title}

13 | {/if} 14 | 15 |
20 |

21 | {#if $$slots.avatar} 22 |
23 | {/if} 24 |
25 |
26 | -------------------------------------------------------------------------------- /src/components/entity/entity.test.ts: -------------------------------------------------------------------------------- 1 | context('Entity', () => { 2 | it('is accessible', () => { 3 | cy.loadStory('Components/Entity', 'Default') 4 | cy.checkAccessibility() 5 | }) 6 | }) 7 | 8 | export {} 9 | -------------------------------------------------------------------------------- /src/components/footer/footer-column/footer-column.stories.svelte: -------------------------------------------------------------------------------- 1 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | Home 28 | Resources 29 | 30 | 31 | About 32 | Contact 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/components/footer/footer-column/footer-column.svelte: -------------------------------------------------------------------------------- 1 | 3 | 4 |
5 | 6 |
7 | -------------------------------------------------------------------------------- /src/components/footer/footer-group/footer-group.stories.svelte: -------------------------------------------------------------------------------- 1 | 30 | 31 | 32 | 33 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/components/footer/footer-group/footer-group.svelte: -------------------------------------------------------------------------------- 1 | 10 | 11 |
12 | 13 |
17 |

{title}

18 | 28 |
29 |
    30 | 31 |
32 |
33 | -------------------------------------------------------------------------------- /src/components/footer/footer-group/footer-group.test.ts: -------------------------------------------------------------------------------- 1 | context('FooterGroup', () => { 2 | it('it functions', () => { 3 | cy.loadStory('Components/Footer/FooterGroup', 'Default') 4 | cy.checkAccessibility() 5 | 6 | cy.screenSize('sm') 7 | cy.checkAccessibility() 8 | cy.contains('Home').should('not.be.visible') 9 | cy.get('h3:visible').contains('Other').click() 10 | cy.contains('Home').should('be.visible') 11 | cy.get('h3:visible').contains('Other').click() 12 | cy.contains('Home').should('not.be.visible') 13 | 14 | cy.tab().realPress(' ') 15 | cy.contains('Home').should('be.visible') 16 | cy.realPress(' ') 17 | cy.contains('Home').should('not.be.visible') 18 | }) 19 | }) 20 | 21 | export {} 22 | -------------------------------------------------------------------------------- /src/components/footer/footer-link/footer-link.stories.svelte: -------------------------------------------------------------------------------- 1 | 29 | 30 | 31 | 32 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/components/footer/footer-link/footer-link.svelte: -------------------------------------------------------------------------------- 1 | 4 | 5 |
  • 6 | 12 | 13 | 14 |
  • 15 | -------------------------------------------------------------------------------- /src/components/footer/footer-social-link-wrapper/footer-social-link-wrapper.svelte: -------------------------------------------------------------------------------- 1 | 3 | 4 |
    5 | 6 |
    7 | -------------------------------------------------------------------------------- /src/components/footer/footer-social-link/footer-social-link.svelte: -------------------------------------------------------------------------------- 1 | 5 | 6 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/components/footer/footer.svelte: -------------------------------------------------------------------------------- 1 | 9 | 10 |
    16 |
    17 | {#if $$slots.default} 18 | 21 | {/if} 22 | {#if $$slots.subfooter} 23 |
    26 | 27 |
    28 | {/if} 29 |
    30 |
    31 | -------------------------------------------------------------------------------- /src/components/footer/footer.test.ts: -------------------------------------------------------------------------------- 1 | context('Footer', () => { 2 | it('functions correctly', () => { 3 | cy.loadStory('Components/Footer', 'Subfooter') 4 | cy.checkAccessibility() 5 | cy.screenSize('md') 6 | cy.checkAccessibility() 7 | cy.screenSize('sm') 8 | cy.checkAccessibility() 9 | 10 | cy.get('[data-test="footer-link"]').should('not.be.visible') 11 | cy.get('[data-test="footer-group-title"]:visible').first().click() 12 | cy.get('[data-test="footer-link"]').should('be.visible') 13 | cy.get('[data-test="footer-group-title"]:visible').first().click() 14 | cy.get('[data-test="footer-link"]').should('not.be.visible') 15 | 16 | cy.tab().realPress(' ') 17 | cy.get('[data-test="footer-link"]').should('be.visible') 18 | cy.realPress(' ') 19 | cy.get('[data-test="footer-link"]').should('not.be.visible') 20 | cy.tab().realPress(' ') 21 | cy.get('[data-test="footer-link"]').should('be.visible') 22 | cy.realPress(' ') 23 | cy.get('[data-test="footer-link"]').should('not.be.visible') 24 | }) 25 | }) 26 | 27 | export {} 28 | -------------------------------------------------------------------------------- /src/components/header/header-brand/header-brand.svelte: -------------------------------------------------------------------------------- 1 | 11 | 12 | 18 | {#if image} 19 | 20 | {/if} 21 | 22 |

    {text}

    23 |
    24 |
    25 | -------------------------------------------------------------------------------- /src/components/header/header-dropdown/header-dropdown.test.ts: -------------------------------------------------------------------------------- 1 | const content = '[data-test="header-dropdown-content"]' 2 | 3 | context('HeaderDropdown', () => { 4 | it('renders', () => { 5 | cy.loadStory('Components/Header/HeaderDropdown', 'Default') 6 | cy.checkAccessibility() 7 | cy.get(content).should('not.exist') 8 | cy.get('button').realHover() 9 | cy.get(content).should('exist') 10 | cy.get(content).realHover() 11 | cy.get(content).should('exist') 12 | cy.get('body').realHover({ position: 'topLeft' }) 13 | cy.get(content).should('not.exist') 14 | 15 | cy.get('button').realClick() 16 | cy.get(content).should('exist') 17 | cy.get(content).realClick() 18 | cy.get(content).should('exist') 19 | }) 20 | }) 21 | 22 | export {} 23 | -------------------------------------------------------------------------------- /src/components/header/header-item-wrapper/header-item-wrapper.svelte: -------------------------------------------------------------------------------- 1 | 12 | 13 |
    14 | 15 |
    16 | -------------------------------------------------------------------------------- /src/components/header/header-item-wrapper/header-item-wrapper.test.ts: -------------------------------------------------------------------------------- 1 | context('HeaderItemWrapper', () => { 2 | it('responds to breakpoints', () => { 3 | cy.loadStory('Components/Header/HeaderItemWrapper', 'Breakpoints') 4 | 5 | cy.contains("breakpoint='none'").should('be.visible') 6 | cy.contains("breakpoint='sm'").should('be.visible') 7 | cy.contains("breakpoint='md'").should('be.visible') 8 | cy.checkAccessibility() 9 | 10 | cy.screenSize('md') 11 | cy.contains("breakpoint='none'").should('be.visible') 12 | cy.contains("breakpoint='sm'").should('be.visible') 13 | cy.contains("breakpoint='md'").should('not.be.visible') 14 | cy.checkAccessibility() 15 | 16 | cy.screenSize('sm') 17 | cy.contains("breakpoint='none'").should('be.visible') 18 | cy.contains("breakpoint='sm'").should('not.be.visible') 19 | cy.contains("breakpoint='md'").should('not.be.visible') 20 | cy.checkAccessibility() 21 | }) 22 | }) 23 | 24 | export {} 25 | -------------------------------------------------------------------------------- /src/components/header/header-item-wrapper/index.d.ts: -------------------------------------------------------------------------------- 1 | export type HeaderItemBreakpoint = 'sm' | 'md' | 'none' 2 | -------------------------------------------------------------------------------- /src/components/header/header-link/header-link.test.ts: -------------------------------------------------------------------------------- 1 | context('HeaderLink', () => { 2 | it('responds to breakpoints', () => { 3 | cy.loadStory('Components/Header/HeaderLink', 'Breakpoints') 4 | 5 | cy.get('a').contains('none').should('be.visible') 6 | cy.get('a').contains('sm').should('be.visible') 7 | cy.get('a').contains('md').should('be.visible') 8 | cy.checkAccessibility() 9 | 10 | cy.screenSize('md') 11 | cy.get('a').contains('none').should('be.visible') 12 | cy.get('a').contains('sm').should('be.visible') 13 | cy.get('a').contains('md').should('not.be.visible') 14 | cy.checkAccessibility() 15 | 16 | cy.screenSize('sm') 17 | cy.get('a').contains('none').should('be.visible') 18 | cy.get('a').contains('sm').should('not.be.visible') 19 | cy.get('a').contains('md').should('not.be.visible') 20 | cy.checkAccessibility() 21 | }) 22 | }) 23 | 24 | export {} 25 | -------------------------------------------------------------------------------- /src/components/header/header-mobile-group/header-mobile-group.stories.svelte: -------------------------------------------------------------------------------- 1 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | Docs 36 | About 37 | Contact 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/components/header/header-mobile-group/header-mobile-group.svelte: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 |

    {title}

    9 |
    10 | 11 | 12 | -------------------------------------------------------------------------------- /src/components/header/header-mobile-group/header-mobile-group.test.ts: -------------------------------------------------------------------------------- 1 | context('HeaderMobileGroup', () => { 2 | it('renders', () => { 3 | cy.loadStory('Components/Header/HeaderMobileGroup', 'Default') 4 | cy.checkAccessibility() 5 | }) 6 | }) 7 | 8 | export {} 9 | -------------------------------------------------------------------------------- /src/components/header/header-mobile-item-wrapper/header-mobile-item-wrapper.stories.svelte: -------------------------------------------------------------------------------- 1 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/components/header/header-mobile-item-wrapper/header-mobile-item-wrapper.svelte: -------------------------------------------------------------------------------- 1 | 5 | 6 |
    7 |
    8 | 9 |
    10 |
    11 | -------------------------------------------------------------------------------- /src/components/header/header-mobile-item-wrapper/header-mobile-item-wrapper.test.ts: -------------------------------------------------------------------------------- 1 | context('HeaderMobileItemWrapper', () => { 2 | it('renders', () => { 3 | cy.loadStory('Components/Header/HeaderMobileItemWrapper', 'Default') 4 | cy.checkAccessibility() 5 | }) 6 | }) 7 | 8 | export {} 9 | -------------------------------------------------------------------------------- /src/components/header/header-mobile-link/header-mobile-link.stories.svelte: -------------------------------------------------------------------------------- 1 | 35 | 36 | 37 | 38 | 39 | Docs 40 | 41 | -------------------------------------------------------------------------------- /src/components/header/header-mobile-link/header-mobile-link.test.ts: -------------------------------------------------------------------------------- 1 | context('HeaderMobileLink', () => { 2 | it('renders', () => { 3 | cy.loadStory('Components/Header/HeaderMobileLink', 'Default') 4 | cy.checkAccessibility() 5 | }) 6 | }) 7 | 8 | export {} 9 | -------------------------------------------------------------------------------- /src/components/header/header-mobile-subgroup/header-mobile-subgroup.svelte: -------------------------------------------------------------------------------- 1 | 23 | 24 | 25 | {#if isActive || visible} 26 | 27 | 28 | 29 | {/if} 30 | -------------------------------------------------------------------------------- /src/components/header/header-mobile-subgroup/header-mobile-subgroup.test.ts: -------------------------------------------------------------------------------- 1 | context('HeaderMobileSubgroup', () => { 2 | it('renders', () => { 3 | cy.loadStory('Components/Header/HeaderMobileSubgroup', 'Default') 4 | cy.checkAccessibility() 5 | }) 6 | }) 7 | 8 | export {} 9 | -------------------------------------------------------------------------------- /src/components/header/index.d.ts: -------------------------------------------------------------------------------- 1 | import type { Writable } from 'svelte/store' 2 | 3 | export type HeaderContext = 4 | | { 5 | currentPage: Writable 6 | sticky: Writable 7 | scrolledToTop: Writable 8 | } 9 | | undefined 10 | -------------------------------------------------------------------------------- /src/components/header/subheader/index.d.ts: -------------------------------------------------------------------------------- 1 | import type { Writable } from 'svelte/store' 2 | 3 | export type SubheaderContext = true | undefined 4 | -------------------------------------------------------------------------------- /src/components/header/subheader/subheader.stories.svelte: -------------------------------------------------------------------------------- 1 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/components/header/subheader/subheader.test.ts: -------------------------------------------------------------------------------- 1 | context('Subheader', () => { 2 | it('renders', () => { 3 | cy.loadStory('Components/Header/Subheader', 'Default') 4 | cy.checkAccessibility() 5 | }) 6 | }) 7 | 8 | export {} 9 | -------------------------------------------------------------------------------- /src/components/list/index.d.ts: -------------------------------------------------------------------------------- 1 | import type { Writable } from 'svelte/store' 2 | import type { ListItemVariant, ListItemShape } from './list-item' 3 | 4 | export type ListMode = 'display' | 'interactive' | 'singleSelect' 5 | export type ListRole = 'list' | 'listbox' | 'menu' 6 | export type RegisterListItem = (options: { selected: boolean; key: string }) => void 7 | export type ListContext = 8 | | { 9 | itemKeys: Writable 10 | focusedItem: Writable 11 | selectedItem: Writable 12 | registerListItem: registerListItem 13 | variantStore: Writable 14 | shapeStore: Writable 15 | modeStore: Writable 16 | compactStore: Writable 17 | roleStore: Writable 18 | } 19 | | undefined 20 | 21 | export type ListChangeDetail = { index: number } 22 | export type ListOnChange = CustomEvent 23 | export type ListDispatcher = { 24 | change: ListChangeDetail 25 | } 26 | -------------------------------------------------------------------------------- /src/components/list/list-divider/list-divider.stories.svelte: -------------------------------------------------------------------------------- 1 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/components/list/list-divider/list-divider.svelte: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/components/list/list-divider/list-divider.test.ts: -------------------------------------------------------------------------------- 1 | context('ListDivider', () => { 2 | it('renders', () => { 3 | cy.loadStory('Components/List/ListDivider', 'Default') 4 | cy.checkAccessibility() 5 | }) 6 | }) 7 | 8 | export {} 9 | -------------------------------------------------------------------------------- /src/components/list/list-item/index.d.ts: -------------------------------------------------------------------------------- 1 | export type ListItemVariant = 'primary' | 'error' | 'success' | 'warning' | 'gray' | 'highlight' 2 | export type ListItemShape = 'rounded' | 'square' 3 | -------------------------------------------------------------------------------- /src/components/list/list-item/list-item.test.ts: -------------------------------------------------------------------------------- 1 | context('ListItem', () => { 2 | it('renders', () => { 3 | cy.loadStory('Components/List/ListItem', 'Default') 4 | cy.checkAccessibility() 5 | }) 6 | }) 7 | 8 | export {} 9 | -------------------------------------------------------------------------------- /src/components/media-scroller/media-scroller.test.ts: -------------------------------------------------------------------------------- 1 | context('MediaScroller', () => { 2 | it('renders', () => { 3 | cy.loadStory('Components/MediaScroller', 'Default') 4 | cy.checkAccessibility() 5 | }) 6 | }) 7 | 8 | export {} 9 | -------------------------------------------------------------------------------- /src/components/modal/index.d.ts: -------------------------------------------------------------------------------- 1 | export type ModalDispatcher = { 2 | cancel: never 3 | confirm: never 4 | close: never 5 | } 6 | export type FormOnError = CustomEvent 7 | export type FormOnStateChange = CustomEvent 8 | -------------------------------------------------------------------------------- /src/components/popover/index.d.ts: -------------------------------------------------------------------------------- 1 | export type PopoverPlacement = 2 | | 'top' 3 | | 'right' 4 | | 'bottom' 5 | | 'left' 6 | | 'top-start' 7 | | 'top-end' 8 | | 'right-start' 9 | | 'right-end' 10 | | 'left-start' 11 | | 'left-end' 12 | | 'bottom-start' 13 | | 'bottom-end' 14 | -------------------------------------------------------------------------------- /src/components/popover/popover.test.ts: -------------------------------------------------------------------------------- 1 | context('Popover', () => { 2 | it('functions correctly', () => { 3 | cy.loadStory('Components/Popover', 'Default') 4 | cy.checkAccessibility() 5 | 6 | cy.get('[data-test="popover"]').should('not.exist') 7 | cy.get('[data-test="button"]').click() 8 | cy.get('[data-test="popover"]').should('exist') 9 | cy.checkAccessibility() 10 | cy.get('body').click() 11 | cy.get('[data-test="popover"]').should('not.exist') 12 | 13 | cy.tab().realType(' ') 14 | cy.get('[data-test="popover"]').should('exist') 15 | cy.realPress('Escape') 16 | cy.get('[data-test="popover"]').should('not.exist') 17 | 18 | cy.realType(' ') 19 | cy.get('[data-test="popover"]').should('exist') 20 | cy.realType(' ') 21 | cy.get('[data-test="popover"]').should('not.exist') 22 | 23 | cy.get('[data-test="button"]').should('be.focused') 24 | }) 25 | 26 | it('calls hooks', () => { 27 | cy.loadStory('Components/Popover', 'Events') 28 | cy.checkAccessibility() 29 | 30 | cy.get('[data-test="button"]').click() 31 | cy.on('window:alert', cy.stub().as('alerted')) 32 | cy.get('body').click() 33 | cy.on('window:alert', cy.stub().as('alerted')) 34 | }) 35 | }) 36 | 37 | export {} 38 | -------------------------------------------------------------------------------- /src/components/table-of-contents/index.d.ts: -------------------------------------------------------------------------------- 1 | export type TocItem = { href: string; text: string } 2 | export type SectionItem = TocItem & { children: TocItem[] } 3 | export type TocItems = (TocItem | SectionItem)[] 4 | -------------------------------------------------------------------------------- /src/components/table-of-contents/table-of-contents.test.ts: -------------------------------------------------------------------------------- 1 | context('TableOfContents', () => { 2 | it('renders', () => { 3 | cy.loadStory('Navigation/TableOfContents', 'Default') 4 | cy.checkAccessibility() 5 | }) 6 | }) 7 | 8 | export {} 9 | -------------------------------------------------------------------------------- /src/components/tabs/tab-item/tab-item.test.ts: -------------------------------------------------------------------------------- 1 | context('TabItem', () => { 2 | it('renders', () => { 3 | cy.loadStory('Navigation/Tabs/TabItem', 'Default') 4 | cy.checkAccessibility() 5 | }) 6 | }) 7 | 8 | export {} 9 | -------------------------------------------------------------------------------- /src/components/toast/index.ts: -------------------------------------------------------------------------------- 1 | import { writable } from 'svelte/store' 2 | 3 | export type ToastVariant = 'default' | 'error' | 'success' 4 | 5 | export type Toast = { 6 | text: string 7 | action?: { 8 | text: string 9 | onClick: () => void 10 | } 11 | cancel?: { 12 | text: string 13 | onClick: () => void 14 | } 15 | variant?: ToastVariant 16 | duration?: number 17 | } 18 | 19 | export type _ToastItem = Toast & { key: string } 20 | 21 | export const _toasts = writable<_ToastItem[]>([]) 22 | 23 | export const showToast = (toast: Toast): void => { 24 | _toasts.update((previous) => [ 25 | ...previous, 26 | { ...toast, key: String(Date.now() + Math.random()) }, 27 | ]) 28 | } 29 | -------------------------------------------------------------------------------- /src/components/toast/toast.svelte: -------------------------------------------------------------------------------- 1 | 8 | 9 |
    14 | {#each $_toasts as item, index (item.key)} 15 | 20 | {/each} 21 |
    22 | -------------------------------------------------------------------------------- /src/components/toast/toast.test.ts: -------------------------------------------------------------------------------- 1 | context('Toast', () => { 2 | it('renders', () => { 3 | cy.loadStory('Components/Toast', 'Default') 4 | cy.checkAccessibility() 5 | }) 6 | }) 7 | 8 | export {} 9 | -------------------------------------------------------------------------------- /src/components/tooltip/tooltip.test.ts: -------------------------------------------------------------------------------- 1 | context('Tooltip', () => { 2 | it('functions', () => { 3 | cy.loadStory('Components/Tooltip', 'Default') 4 | cy.checkAccessibility() 5 | cy.get('[data-test="tooltip"]').should('not.exist') 6 | cy.tab() 7 | cy.get('[data-test="tooltip"]').should('be.visible') 8 | cy.realPress('Tab') 9 | cy.get('[data-test="tooltip"]').should('not.exist') 10 | cy.get('button').realHover() 11 | cy.get('[data-test="tooltip"]').should('be.visible') 12 | }) 13 | }) 14 | 15 | export {} 16 | -------------------------------------------------------------------------------- /src/components/youtube-video/youtube-video.stories.svelte: -------------------------------------------------------------------------------- 1 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/components/youtube-video/youtube-video.test.ts: -------------------------------------------------------------------------------- 1 | context('YoutubeVideo', () => { 2 | it('renders', () => { 3 | cy.loadStory('Components/YoutubeVideo', 'Default') 4 | cy.checkAccessibility() 5 | }) 6 | }) 7 | 8 | export {} 9 | -------------------------------------------------------------------------------- /src/configs/transitions.ts: -------------------------------------------------------------------------------- 1 | export type TransitionSpeed = 'none' | 'small' | 'medium' | 'large' | 'larger' 2 | 3 | export const TRANSITION_SPEED_MAP: Record< 4 | TransitionSpeed, 5 | { in: number; out: number; default: number } 6 | > = Object.freeze({ 7 | none: { 8 | in: 0, 9 | out: 0, 10 | default: 0, 11 | }, 12 | small: { 13 | in: 150, 14 | out: 100, 15 | default: 150, 16 | }, 17 | medium: { 18 | in: 250, 19 | out: 200, 20 | default: 250, 21 | }, 22 | large: { 23 | in: 300, 24 | out: 225, 25 | default: 300, 26 | }, 27 | larger: { 28 | in: 500, 29 | out: 425, 30 | default: 500, 31 | }, 32 | }) 33 | -------------------------------------------------------------------------------- /src/elements/button/button.test.ts: -------------------------------------------------------------------------------- 1 | context('Button', () => { 2 | it('is accessible', () => { 3 | cy.loadStory('Elements/Button', 'Default') 4 | cy.checkAccessibility() 5 | 6 | cy.loadStory('Elements/Button', 'Variants') 7 | cy.checkAccessibility() 8 | 9 | cy.loadStory('Elements/Button', 'Hovered') 10 | cy.checkAccessibility() 11 | 12 | cy.loadStory('Elements/Button', 'Focused') 13 | cy.checkAccessibility() 14 | 15 | cy.loadStory('Elements/Button', 'Sizes') 16 | cy.checkAccessibility() 17 | 18 | cy.loadStory('Elements/Button', 'Shapes') 19 | cy.checkAccessibility() 20 | 21 | cy.loadStory('Elements/Button', 'Width') 22 | cy.checkAccessibility() 23 | 24 | cy.loadStory('Elements/Button', 'Prefix and suffix') 25 | cy.checkAccessibility() 26 | 27 | cy.loadStory('Elements/Button', 'Disabled') 28 | cy.checkAccessibility() 29 | 30 | cy.loadStory('Elements/Button', 'Loading') 31 | cy.checkAccessibility() 32 | }) 33 | }) 34 | 35 | export {} 36 | -------------------------------------------------------------------------------- /src/elements/dark-mode-select/dark-mode-select.stories.svelte: -------------------------------------------------------------------------------- 1 | 31 | 32 | 33 | 34 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/elements/dark-mode-select/dark-mode-select.svelte: -------------------------------------------------------------------------------- 1 | 21 | 22 | 33 | -------------------------------------------------------------------------------- /src/elements/error/error.test.ts: -------------------------------------------------------------------------------- 1 | context('Error', () => { 2 | it('renders', () => { 3 | cy.loadStory('Elements/Error', 'Default') 4 | cy.checkAccessibility() 5 | }) 6 | }) 7 | 8 | export {} 9 | -------------------------------------------------------------------------------- /src/elements/icon/activity.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/arrow-down-left.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/arrow-down.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/arrow-left.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/arrow-right.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/arrow-up-left.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/arrow-up-right.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/arrow-up.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/bluetooth.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/bookmark.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/check.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/chevron-down.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/chevron-left.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/chevron-right.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/chevron-up.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/chevrons-up.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/circle.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/clock.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/cloud.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/code.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/corner-down-left.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/corner-left-up.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/corner-right-up.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/corner-up-left.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/corner-up-right.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/crop.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/disc.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/divider.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/dot.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/droplet.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/edit-2.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/eye.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/filter.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/folder.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/framer.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/heading-1.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/message-square.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/minus-circle.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/minus.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/moon.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/mouse-pointer.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/navigation-2.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/navigation.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/pause.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/pie-chart.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/play-circle.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/play.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/plus.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/power.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/shield.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/square.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/stop-circle.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/terminal.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/thermometer.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/twitch.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/umbrella.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/volume.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/x.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/icon/zap.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 36 | {#if title} 37 | {title} 38 | {/if} 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/elements/loading-dots/loading-dots.stories.svelte: -------------------------------------------------------------------------------- 1 | 19 | 20 | 21 | 22 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/elements/loading-progress-indicator/loading-progress-indicator.stories.svelte: -------------------------------------------------------------------------------- 1 | 20 | 21 | 22 | 23 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/elements/loading-progress-indicator/loading-progress-indicator.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | {#each count as _} 24 | 25 | {/each} 26 | -------------------------------------------------------------------------------- /src/elements/loading-section/loading-section.stories.svelte: -------------------------------------------------------------------------------- 1 | 30 | 31 | 32 | 33 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/elements/loading-section/loading-section.svelte: -------------------------------------------------------------------------------- 1 | 13 | 14 |
    15 | 16 |
    17 | -------------------------------------------------------------------------------- /src/elements/loading-spinner/loading-spinner.stories.svelte: -------------------------------------------------------------------------------- 1 | 19 | 20 | 21 | 22 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/elements/loading-spinner/loading-spinner.svelte: -------------------------------------------------------------------------------- 1 | 4 | 5 |
    11 | -------------------------------------------------------------------------------- /src/elements/marketing-icon/storybook/marketing-icon.stories.svelte: -------------------------------------------------------------------------------- 1 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/elements/marketing-icon/storybook/marketing-icon.test.ts: -------------------------------------------------------------------------------- 1 | context('MarketingIcon', () => { 2 | it('renders', () => { 3 | cy.loadStory('Elements/MarketingIcon', 'Default') 4 | cy.checkAccessibility() 5 | }) 6 | }) 7 | 8 | export {} 9 | -------------------------------------------------------------------------------- /src/elements/note/note.test.ts: -------------------------------------------------------------------------------- 1 | context('Note', () => { 2 | it('renders', () => { 3 | cy.loadStory('Elements/Note', 'Default') 4 | cy.checkAccessibility() 5 | }) 6 | }) 7 | 8 | export {} 9 | -------------------------------------------------------------------------------- /src/elements/progress-bar/progress-bar.svelte: -------------------------------------------------------------------------------- 1 | 27 | 28 |
    36 |
    37 |
    41 |
    42 | -------------------------------------------------------------------------------- /src/elements/status-dot/status-dot.svelte: -------------------------------------------------------------------------------- 1 | 17 | 18 |
    19 |
    20 | {#if ping} 21 |
    22 | {/if} 23 |
    24 | -------------------------------------------------------------------------------- /src/form/form-entity/index.d.ts: -------------------------------------------------------------------------------- 1 | export type DescriptionLink = { 2 | value: string 3 | href: string 4 | } 5 | export type ErrorMessages = { 6 | default: string 7 | offline: string | false 8 | 403: string | false 9 | 429: string | false 10 | 400: string | false 11 | 500: string | false 12 | } 13 | export type FormEntityDispatcher = { 14 | primaryClick: MouseEvent 15 | secondaryClick: MouseEvent 16 | destructiveClick: MouseEvent 17 | } 18 | -------------------------------------------------------------------------------- /src/form/form-feedback.ts: -------------------------------------------------------------------------------- 1 | export const FORM_FEEDBACK = Object.freeze({ 2 | errors: { 3 | default: 'There was an internal error. Please try again.', 4 | offline: 'You are offline. Connect to the internet and try again.', 5 | 403: 'You are not authorized to make this request.', 6 | 429: 'You are making too many requests. Wait a few minutes and try again.', 7 | 400: 'There was an internal error. Please try again.', 8 | 500: 'There was an internal error. Please try again.', 9 | }, 10 | success: { 11 | default: 'Submitted successfully', 12 | saved: 'Saved successfully', 13 | }, 14 | auth: { 15 | errors: { 16 | noEmailFound: 'There is not an account with that email.', 17 | invalidEmailLogin: 'Invalid email or password. Try again.', 18 | resetPasswordLinkExpired: 19 | 'Password reset link expired. Request a new link and try again.', 20 | }, 21 | success: { 22 | passwordIsReset: 'Your password is reset and you can sign in', 23 | passwordResetLinkSent: 'Check your email for the password reset link.', 24 | }, 25 | }, 26 | }) 27 | -------------------------------------------------------------------------------- /src/form/inputs/avatar-input/avatar-input.test.ts: -------------------------------------------------------------------------------- 1 | context('AvatarInput', () => { 2 | it('renders', () => { 3 | cy.loadStory('Form/Inputs/AvatarInput', 'Default') 4 | cy.checkAccessibility() 5 | }) 6 | }) 7 | 8 | export {} 9 | -------------------------------------------------------------------------------- /src/form/inputs/avatar-input/index.d.ts: -------------------------------------------------------------------------------- 1 | export type ErrorEventDetail = { 2 | isValid: boolean 3 | errorMessage: string 4 | } 5 | export type AvatarInputErrorEvent = CustomEvent 6 | export type AvatarInputDispatcher = { 7 | error: ErrorEventDetail 8 | } 9 | -------------------------------------------------------------------------------- /src/form/inputs/check-input/index.d.ts: -------------------------------------------------------------------------------- 1 | export type CheckboxValue = 'unchecked' | 'checked' | 'indeterminate' 2 | -------------------------------------------------------------------------------- /src/form/inputs/date-input/date-input.test.ts: -------------------------------------------------------------------------------- 1 | context('DateInput', () => { 2 | it('renders', () => { 3 | cy.loadStory('Form/Inputs/DateInput', 'Default') 4 | cy.checkAccessibility() 5 | }) 6 | }) 7 | 8 | export {} 9 | -------------------------------------------------------------------------------- /src/form/inputs/dollar-input/dollar-input.test.ts: -------------------------------------------------------------------------------- 1 | context('DollarInput', () => { 2 | it('renders', () => { 3 | cy.loadStory('Form/Inputs/DollarInput', 'Default') 4 | cy.checkAccessibility() 5 | }) 6 | }) 7 | 8 | export {} 9 | -------------------------------------------------------------------------------- /src/form/inputs/email-input/email-input.test.ts: -------------------------------------------------------------------------------- 1 | context('EmailInput', () => { 2 | it('can detect invalid emails', () => { 3 | cy.loadStory('Form/Inputs/EmailInput', 'Default', { 4 | optional: 'true', 5 | }) 6 | cy.checkAccessibility() 7 | const invalidValues = ['invalid', 'invalid@example.'] 8 | invalidValues.forEach((value) => { 9 | cy.get('input').clear().type(value).blur() 10 | cy.get('[data-test="error"]').should('exist') 11 | cy.get('input').clear().blur() 12 | cy.get('[data-test="error"]').should('not.exist') 13 | }) 14 | }) 15 | }) 16 | 17 | export {} 18 | -------------------------------------------------------------------------------- /src/form/inputs/facebook-page-input/facebook-page-input.test.ts: -------------------------------------------------------------------------------- 1 | context('FacebookPageInput', () => { 2 | it('renders', () => { 3 | cy.loadStory('Form/Inputs/FacebookPageInput', 'Default') 4 | cy.checkAccessibility() 5 | }) 6 | }) 7 | 8 | export {} 9 | -------------------------------------------------------------------------------- /src/form/inputs/file-input/file-input.stories.svelte: -------------------------------------------------------------------------------- 1 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/form/inputs/file-input/file-input.test.ts: -------------------------------------------------------------------------------- 1 | context('FileInput', () => { 2 | it('renders', () => { 3 | cy.loadStory('Form/Inputs/FileInput', 'Default') 4 | cy.checkAccessibility() 5 | }) 6 | }) 7 | 8 | export {} 9 | -------------------------------------------------------------------------------- /src/form/inputs/image-input/image-input.test.ts: -------------------------------------------------------------------------------- 1 | context('ImageInput', () => { 2 | it('renders', () => { 3 | cy.loadStory('Form/Inputs/ImageInput', 'Default') 4 | cy.checkAccessibility() 5 | }) 6 | }) 7 | 8 | export {} 9 | -------------------------------------------------------------------------------- /src/form/inputs/linkedin-input/linkedin-input.test.ts: -------------------------------------------------------------------------------- 1 | context('LinkedinInput', () => { 2 | it('renders', () => { 3 | cy.loadStory('Form/Inputs/LinkedinInput', 'Default') 4 | cy.checkAccessibility() 5 | }) 6 | }) 7 | 8 | export {} 9 | -------------------------------------------------------------------------------- /src/form/inputs/name-input/name-input.test.ts: -------------------------------------------------------------------------------- 1 | context('NameInput', () => { 2 | it('renders', () => { 3 | cy.loadStory('Form/Inputs/NameInput', 'Default') 4 | cy.checkAccessibility() 5 | }) 6 | }) 7 | 8 | export {} 9 | -------------------------------------------------------------------------------- /src/form/inputs/password-input/password-input.test.ts: -------------------------------------------------------------------------------- 1 | context('PasswordInput', () => { 2 | it('renders', () => { 3 | cy.loadStory('Form/Inputs/PasswordInput', 'Default') 4 | cy.get('input').should('have.attr', 'type', 'password') 5 | cy.get('button').click() 6 | cy.get('input').should('have.attr', 'type', 'text') 7 | cy.contains('Hide password') 8 | cy.get('button').click() 9 | cy.get('input').should('have.attr', 'type', 'password') 10 | cy.contains('Show password') 11 | }) 12 | }) 13 | 14 | export {} 15 | -------------------------------------------------------------------------------- /src/form/inputs/rich-text-input/rich-text-input.test.ts: -------------------------------------------------------------------------------- 1 | context('RichTextInput', () => { 2 | it('renders', () => { 3 | cy.loadStory('Form/Inputs/RichTextInput', 'Default') 4 | cy.checkAccessibility() 5 | }) 6 | }) 7 | 8 | export {} 9 | -------------------------------------------------------------------------------- /src/form/inputs/search-input/_search-input-refresh.svelte: -------------------------------------------------------------------------------- 1 | 8 | 9 |
    10 | 11 |
    12 | -------------------------------------------------------------------------------- /src/form/inputs/text-input/_input-feedback-section.svelte: -------------------------------------------------------------------------------- 1 | 10 | 11 |
    12 |
    13 | {#if isInvalidState} 14 |
    15 | {errorMessage} 16 |
    17 | {:else if helpText} 18 |

    {helpText}

    19 | {/if} 20 | 21 | {#if feedback && !hideFeedback} 22 |

    {feedback}

    23 | {/if} 24 |
    25 |
    26 | -------------------------------------------------------------------------------- /src/form/inputs/twitter-profile-input/twitter-profile-input.test.ts: -------------------------------------------------------------------------------- 1 | context('TwitterProfileInput', () => { 2 | it('renders', () => { 3 | cy.loadStory('Form/Inputs/TwitterProfileInput', 'Default') 4 | cy.checkAccessibility() 5 | }) 6 | }) 7 | 8 | export {} 9 | -------------------------------------------------------------------------------- /src/form/inputs/url-input/url-input.test.ts: -------------------------------------------------------------------------------- 1 | const invalidUrls = [ 2 | 'john smith', 3 | 'hello@example.com', 4 | 'foo@bar.com', 5 | 'http://localhost:3000/', 6 | '//foobar.com', 7 | ] 8 | 9 | const validUrls = [ 10 | 'https://example.com', 11 | 'http://facebook.com/this.is.a.path', 12 | 'foobar.com', 13 | 'www.foobar.com', 14 | 'foobar.com/', 15 | 'valid.au', 16 | ] 17 | 18 | context('UrlInput', () => { 19 | it('renders', () => { 20 | cy.loadStory('Form/Inputs/UrlInput', 'Default', { 21 | optional: 'true', 22 | }) 23 | 24 | invalidUrls.forEach((value) => { 25 | cy.get('input').type(value).blur() 26 | cy.get('[data-test="error"]').should('exist') 27 | cy.get('input').clear().blur() 28 | cy.get('[data-test="error"]').should('not.exist') 29 | }) 30 | validUrls.forEach((value) => { 31 | cy.get('input').type(value).blur() 32 | cy.get('[data-test="error"]').should('not.exist') 33 | cy.contains(`Parsed value: "${value}"`) 34 | cy.get('input').clear() 35 | }) 36 | }) 37 | }) 38 | 39 | export {} 40 | -------------------------------------------------------------------------------- /src/form/inputs/youtube-channel-input/youtube-channel-input.test.ts: -------------------------------------------------------------------------------- 1 | context('YoutubeChannelInput', () => { 2 | it('renders', () => { 3 | cy.loadStory('Form/Inputs/YoutubeChannelInput', 'Default', { 4 | defaultValue: 'YouTubeCreators', 5 | }) 6 | cy.get('input').should('have.value', 'https://youtube.com/YouTubeCreators') 7 | }) 8 | }) 9 | 10 | export {} 11 | -------------------------------------------------------------------------------- /src/form/inputs/youtube-video-input/youtube-video-input.test.ts: -------------------------------------------------------------------------------- 1 | context('YoutubeVideoInput', () => { 2 | it('renders', () => { 3 | cy.loadStory('Form/Inputs/YoutubeVideoInput', 'Default', { 4 | defaultValue: '1234', 5 | }) 6 | cy.get('input').should('have.value', 'https://youtube.com/watch?v=1234') 7 | }) 8 | }) 9 | 10 | export {} 11 | -------------------------------------------------------------------------------- /src/form/label/label.stories.svelte: -------------------------------------------------------------------------------- 1 | 38 | 39 | 40 | 41 | 42 | 44 | -------------------------------------------------------------------------------- /src/form/label/label.svelte: -------------------------------------------------------------------------------- 1 | 13 | 14 | 15 | 29 | -------------------------------------------------------------------------------- /src/form/label/label.test.ts: -------------------------------------------------------------------------------- 1 | context('Label', () => { 2 | it('renders', () => { 3 | cy.loadStory('Form/Label', 'Default') 4 | cy.checkAccessibility() 5 | }) 6 | }) 7 | 8 | export {} 9 | -------------------------------------------------------------------------------- /src/layouts/auth/auth.svelte: -------------------------------------------------------------------------------- 1 | 14 | 15 |
    16 |
    17 | 25 | 26 | 27 | 28 | {#if links.length > 0} 29 |
    30 | {#each links as link} 31 | 32 | {/each} 33 |
    34 | {/if} 35 |
    36 |
    37 | -------------------------------------------------------------------------------- /src/layouts/auth/auth.test.ts: -------------------------------------------------------------------------------- 1 | context('Auth', () => { 2 | it('renders', () => { 3 | cy.loadStory('Layouts/Auth', 'Default') 4 | 5 | cy.checkAccessibility() 6 | cy.get('a').should('have.attr', 'href', '/') 7 | 8 | cy.loadStory('Layouts/Auth', 'With logo') 9 | cy.checkAccessibility() 10 | cy.get('a').should('have.attr', 'href', '/') 11 | 12 | cy.loadStory('Layouts/Auth', 'With links') 13 | cy.checkAccessibility() 14 | cy.get('a').should('have.attr', 'href', '/') 15 | cy.get('a').eq(1).should('have.attr', 'href', '#') 16 | 17 | cy.loadStory('Layouts/Auth', 'Example') 18 | cy.checkAccessibility({ page: true }) 19 | }) 20 | }) 21 | 22 | export {} 23 | -------------------------------------------------------------------------------- /src/layouts/auth/oauth/index.d.ts: -------------------------------------------------------------------------------- 1 | export type OauthTypes = 'apple' | 'facebook' | 'google' | 'twitter' 2 | export type OauthOnClick = CustomEvent 3 | export type OauthDispatcher = { 4 | click: OauthTypes 5 | } 6 | -------------------------------------------------------------------------------- /src/layouts/auth/oauth/oauth.stories.svelte: -------------------------------------------------------------------------------- 1 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/layouts/auth/oauth/oauth.test.ts: -------------------------------------------------------------------------------- 1 | context('Oauth', () => { 2 | it('renders', () => { 3 | cy.loadStory('Layouts/Auth/Oauth', 'Default') 4 | cy.checkAccessibility() 5 | }) 6 | }) 7 | 8 | export {} 9 | -------------------------------------------------------------------------------- /src/layouts/auth/reset-password/reset-password.stories.svelte: -------------------------------------------------------------------------------- 1 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/layouts/changelog/changelog-item-page/changelog-item-page.test.ts: -------------------------------------------------------------------------------- 1 | context('ChangelogItemPage', () => { 2 | it('renders', () => { 3 | cy.loadStory('Layouts/Changelog/ChangelogItemPage', 'Default') 4 | cy.checkAccessibility({ page: true }) 5 | }) 6 | }) 7 | 8 | export {} 9 | -------------------------------------------------------------------------------- /src/layouts/changelog/changelog.test.ts: -------------------------------------------------------------------------------- 1 | context('Changelog', () => { 2 | it('renders', () => { 3 | cy.loadStory('Layouts/Changelog', 'Default') 4 | cy.checkAccessibility({ page: true }) 5 | }) 6 | }) 7 | 8 | export {} 9 | -------------------------------------------------------------------------------- /src/layouts/changelog/index.d.ts: -------------------------------------------------------------------------------- 1 | export type ChangelogItemVariant = 'feature' | 'bug' | 'announcement' | 'improvement' 2 | export type ChangelogImage = { 3 | src?: string 4 | srcSet?: { 5 | src?: string 6 | media?: string 7 | type?: string 8 | sizes?: string 9 | }[] 10 | width?: number 11 | height?: number 12 | } 13 | export type ChangelogItem = { 14 | title: string 15 | slug: string 16 | publishedAt: Date 17 | image: ChangelogImage 18 | 19 | contents: string 20 | variant: ChangelogItemVariant 21 | } 22 | export type ChangelogItems = ChangelogItem[] 23 | -------------------------------------------------------------------------------- /src/layouts/dashboard/dashboard-sidebar/dashboard-sidebar.test.ts: -------------------------------------------------------------------------------- 1 | context('DashboardSidebar', () => { 2 | it('renders', () => { 3 | cy.loadStory('Layouts/Dashboard/DashboardSidebar', 'Default') 4 | cy.checkAccessibility() 5 | cy.get('[data-test="list-item"]').should('be.visible').should('have.length', 3) 6 | cy.get('select').should('not.be.visible') 7 | 8 | cy.screenSize('lg') 9 | cy.get('[data-test="list-item"]').should('be.visible').should('have.length', 3) 10 | cy.get('select').should('not.be.visible') 11 | 12 | cy.screenSize('md') 13 | cy.get('[data-test="list-item"]').should('not.be.visible') 14 | cy.get('select').should('be.visible') 15 | 16 | cy.screenSize('sm') 17 | cy.get('[data-test="list-item"]').should('not.be.visible') 18 | cy.get('select').should('be.visible') 19 | }) 20 | }) 21 | 22 | export {} 23 | -------------------------------------------------------------------------------- /src/layouts/dashboard/dashboard-sidebar/index.d.ts: -------------------------------------------------------------------------------- 1 | export type DashboardSidebarItem = { 2 | value: string 3 | href: string 4 | icon?: unknown 5 | } 6 | -------------------------------------------------------------------------------- /src/layouts/http-404/http-404.svelte: -------------------------------------------------------------------------------- 1 | 7 | 8 |
    9 |
    10 |

    404

    11 |

    {kicker}

    12 |

    {title}

    13 |

    {message}

    14 | {#if links.length > 0} 15 |
    16 | {#each links as link} 17 | {link.text} 18 | {/each} 19 |
    20 | {/if} 21 |
    22 |
    23 | -------------------------------------------------------------------------------- /src/layouts/http-500/http-500.svelte: -------------------------------------------------------------------------------- 1 | 12 | 13 |
    14 |
    15 |

    {status} Error

    16 |
    17 |

    Oops…

    18 |

    Internal error

    19 |

    {isDevelopment ? error.message : message}

    20 |
    21 |
    22 | {#if isDevelopment} 23 |
    25 |             
    26 |         
    27 |                 {#each stack as line}
    28 |                     

    {line}

    29 | {/each} 30 |
    31 |
    32 | {/if} 33 |
    34 | -------------------------------------------------------------------------------- /src/svg-marketing/analytics.svg: -------------------------------------------------------------------------------- 1 | 20 | -------------------------------------------------------------------------------- /src/svg-marketing/at.svg: -------------------------------------------------------------------------------- 1 | 20 | -------------------------------------------------------------------------------- /src/svg-marketing/book-user.svg: -------------------------------------------------------------------------------- 1 | 21 | -------------------------------------------------------------------------------- /src/svg-marketing/bookmark.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/svg-marketing/bug.svg: -------------------------------------------------------------------------------- 1 | 21 | -------------------------------------------------------------------------------- /src/svg-marketing/clipboard.svg: -------------------------------------------------------------------------------- 1 | 21 | -------------------------------------------------------------------------------- /src/svg-marketing/computer-speaker.svg: -------------------------------------------------------------------------------- 1 | 20 | -------------------------------------------------------------------------------- /src/svg-marketing/download.svg: -------------------------------------------------------------------------------- 1 | 21 | -------------------------------------------------------------------------------- /src/svg-marketing/envelope-square.svg: -------------------------------------------------------------------------------- 1 | 20 | -------------------------------------------------------------------------------- /src/svg-marketing/file-music.svg: -------------------------------------------------------------------------------- 1 | 21 | -------------------------------------------------------------------------------- /src/svg-marketing/hands-helping.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/svg-marketing/heart-circle.svg: -------------------------------------------------------------------------------- 1 | 21 | -------------------------------------------------------------------------------- /src/svg-marketing/laptop-code.svg: -------------------------------------------------------------------------------- 1 | 21 | -------------------------------------------------------------------------------- /src/svg-marketing/tv-music.svg: -------------------------------------------------------------------------------- 1 | 21 | -------------------------------------------------------------------------------- /src/svg-marketing/user-edit.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/svg/README.md: -------------------------------------------------------------------------------- 1 | # src/svg 2 | 3 | This folder is used to house all the SVGs for the icons. It does not include the [feather](https://feathericons.com/) icons, only the additional ones. 4 | 5 | This folder is not published to npm. 6 | -------------------------------------------------------------------------------- /src/svg/academic-cap.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/svg/apple.svg: -------------------------------------------------------------------------------- 1 | Apple icon -------------------------------------------------------------------------------- /src/svg/divider.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/svg/dot.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/svg/facebook.svg: -------------------------------------------------------------------------------- 1 | Facebook icon -------------------------------------------------------------------------------- /src/svg/github.svg: -------------------------------------------------------------------------------- 1 | GitHub icon -------------------------------------------------------------------------------- /src/svg/google-maps.svg: -------------------------------------------------------------------------------- 1 | Google Maps icon -------------------------------------------------------------------------------- /src/svg/google.svg: -------------------------------------------------------------------------------- 1 | Google icon -------------------------------------------------------------------------------- /src/svg/heading-1.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/svg/heading-2.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/svg/identification.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/svg/linkedin.svg: -------------------------------------------------------------------------------- 1 | LinkedIn icon -------------------------------------------------------------------------------- /src/svg/list-numbered.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/svg/medium.svg: -------------------------------------------------------------------------------- 1 | Medium icon -------------------------------------------------------------------------------- /src/svg/office-building.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/svg/patreon.svg: -------------------------------------------------------------------------------- 1 | Patreon icon -------------------------------------------------------------------------------- /src/svg/paypal.svg: -------------------------------------------------------------------------------- 1 | PayPal icon -------------------------------------------------------------------------------- /src/svg/quote.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/svg/rss.svg: -------------------------------------------------------------------------------- 1 | RSS icon -------------------------------------------------------------------------------- /src/svg/search.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/svg/spotify.svg: -------------------------------------------------------------------------------- 1 | Spotify icon -------------------------------------------------------------------------------- /src/svg/twitter.svg: -------------------------------------------------------------------------------- 1 | Twitter icon -------------------------------------------------------------------------------- /src/svg/user-group.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/svg/user.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/svg/windows.svg: -------------------------------------------------------------------------------- 1 | Windows icon -------------------------------------------------------------------------------- /src/svg/youtube.svg: -------------------------------------------------------------------------------- 1 | YouTube icon -------------------------------------------------------------------------------- /src/utilities/seo/seo.stories.svelte: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | 20 | 21 | This component does not display anything. 22 | 23 | -------------------------------------------------------------------------------- /src/utilities/seo/seo.test.ts: -------------------------------------------------------------------------------- 1 | context('Seo', () => { 2 | it('renders', () => { 3 | cy.loadStory('Utilities/Seo', 'Default') 4 | cy.checkAccessibility() 5 | }) 6 | }) 7 | 8 | export {} 9 | -------------------------------------------------------------------------------- /src/utilities/spacer/spacer.svelte: -------------------------------------------------------------------------------- 1 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /svelte.config.cjs: -------------------------------------------------------------------------------- 1 | const sveltePreprocess = require('svelte-preprocess') 2 | 3 | module.exports = { 4 | preprocess: sveltePreprocess({ 5 | tsconfigFile: './tsconfig.json', 6 | }), 7 | } 8 | -------------------------------------------------------------------------------- /tailwind.config.cjs: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-var-requires */ 2 | /* eslint-disable import/no-commonjs */ 3 | /* eslint-disable import/unambiguous */ 4 | 5 | const { tailwindExtractor } = require('tailwindcss/lib/lib/purgeUnusedStyles') 6 | 7 | module.exports = { 8 | presets: [require('@nick-mazuk/ui-config').config], 9 | purge: { 10 | content: ['./src/**/*.svelte', './src/**/*.stories.mdx', './src/**/*.ts'], 11 | options: { 12 | defaultExtractor: (content) => [ 13 | // If this stops working, please open an issue at https://github.com/svelte-add/tailwindcss/issues rather than bothering Tailwind Labs about it 14 | ...tailwindExtractor(content), 15 | // Match Svelte class: directives (https://github.com/tailwindlabs/tailwindcss/discussions/1731) 16 | ...[...content.matchAll(/(?:class:)*([\w\d-/:%.]+)/gm)].map( 17 | ([_match, group, ..._rest]) => group 18 | ), 19 | ], 20 | keyframes: true, 21 | }, 22 | }, 23 | } 24 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "moduleResolution": "node", 4 | "target": "es5", 5 | "lib": ["es5", "dom"], 6 | "types": ["cypress", "cypress-axe", "cypress-real-events"], 7 | "importsNotUsedAsValues": "error", 8 | "isolatedModules": true, 9 | "sourceMap": true, 10 | "esModuleInterop": true, 11 | "skipLibCheck": true, 12 | "forceConsistentCasingInFileNames": true, 13 | "downlevelIteration": true, 14 | "allowJs": true, 15 | "checkJs": true, 16 | "strict": true, 17 | "strictNullChecks": true 18 | }, 19 | "include": [ 20 | "src/**/*.d.ts", 21 | "src/**/*.ts", 22 | "src/**/*.svelte", 23 | "test-setup.ts", 24 | "cli/**/*.ts", 25 | "types.d.ts", 26 | "cypress/**/*.ts" 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "trailingSlash": false, 3 | "cleanUrls": true, 4 | "github": { 5 | "silent": true 6 | } 7 | } 8 | --------------------------------------------------------------------------------