{"id":23380904,"url":"https://github.com/askomarov/sound-buttons","last_synced_at":"2026-04-29T01:33:54.395Z","repository":{"id":261027083,"uuid":"882991671","full_name":"askomarov/sound-buttons","owner":"askomarov","description":null,"archived":false,"fork":false,"pushed_at":"2024-11-04T09:10:54.000Z","size":5467,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-08T07:44:58.279Z","etag":null,"topics":["astrojs","custom-components","cva","tailwind-merge","tailwindcss"],"latest_commit_sha":null,"homepage":"https://askomarov.github.io/sound-buttons/","language":"Astro","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/askomarov.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-11-04T07:23:59.000Z","updated_at":"2024-11-04T09:13:37.000Z","dependencies_parsed_at":"2024-11-04T10:18:13.464Z","dependency_job_id":"ac49641f-1203-409f-a802-fe9a5f46dd2d","html_url":"https://github.com/askomarov/sound-buttons","commit_stats":null,"previous_names":["askomarov/sound-buttons"],"tags_count":0,"template":false,"template_full_name":"askomarov/astro-template","purl":"pkg:github/askomarov/sound-buttons","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/askomarov%2Fsound-buttons","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/askomarov%2Fsound-buttons/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/askomarov%2Fsound-buttons/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/askomarov%2Fsound-buttons/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/askomarov","download_url":"https://codeload.github.com/askomarov/sound-buttons/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/askomarov%2Fsound-buttons/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32407164,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-28T19:38:08.556Z","status":"ssl_error","status_checked_at":"2026-04-28T19:37:55.688Z","response_time":56,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["astrojs","custom-components","cva","tailwind-merge","tailwindcss"],"created_at":"2024-12-21T20:19:59.572Z","updated_at":"2026-04-29T01:33:54.381Z","avatar_url":"https://github.com/askomarov.png","language":"Astro","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Гайд по работе со сборкой\n\nДля начала работы у вас должент быть установлен Node.js 18\n\n## 🚀 Структура проекта\n\nВнутри проекта вы увидете следующие папки и файлы:\n\n```text\n/\n├── public/\n│   ├── favicon.svg\n│   ├── fonts/\n│   └── svg/\n├── src/\n│   ├── components/\n│   │   ├── Container/\n│   │   │   ├── Container.astro\n│   │   │   └── Container.scss\n│   │   └── ...\n│   └── icons/\n│   └── img/\n│   ├── layouts/\n│   │   ├── root/\n│   │   │   └── root.astro\n│   │   ├── Main/\n│   │   │   └── Main.astro\n│   │   └── ...\n│   ├── pages/\n│   │   ├── index.astro\n│   │   ├── sitemap.astro\n│   │   └── ui-kit.astro\n│   ├── styles/\n│   │   ├── components/\n│   │   ├── global/\n│   │   ├── vendors/\n│   │   └── index.scss\n│   ├── scripts/\n│   │   ├── modules/\n│   │   ├── utils/\n│   │   └── index.js\n├── util/\n└── package.json\n```\n\nВсе статические файлы, например `svg` или шрифты, могут лежать в папке `public/`. Оттуда все файлы автоматически попадают в билд.\n\n## 🐱‍💻 Команды\n\nВсе команды запускаются из корня проекта:\n\n| Command                               | Action                                                |\n| :------------------------------------ | :---------------------------------------------------- |\n| `npm install`                         | Установить зависимости                                |\n| `npm run dev`                         | Запустить локальный дев сервер `localhost:4321`       |\n| `npm run start`                       | Запустить сервер c IP адресом `localhost:IP`          |\n| `npm run build`                       | Собрать билд для продакшна `./dist/`                  |\n| `npm run preview`                     | Посмотреть билд локально перед деплоем                |\n| `npm run astro -- --help`             | Получить помощь в использовании Astro CLI             |\n| `npm run lint`                        | Запустить линтер с автоисправлениями                  |\n| `npm run gen:component name`          | Создать компонент Astro по шаблону в папку components |\n| `npm run gen:component name --ui`     | Создать ui компонент Astro по шаблону                 |\n| `npm run gen:component name --layout` | Создать layout компонент Astro по шаблону             |\n\n## 🎴 Картинки\n\nЕсть два варианта для использования картинок:\n\n1. Использовать компонент астро Picture. Он автоматически генерирует х1, х2, webp и avif. Автоматически подставляет ширину и высоту. [Документация](https://docs.astro.build/en/guides/img/)\n2. В сборке настроен Old Style Way с помощью gulp\n\nМиксин генерирует все изображения из изначальной картинки (х1, х2, webp, avif)\nнужно только изначально прокинуть картинку х2\n\nИспользуйте по согласованию с бэком или если бэка нет.\nОбязательно нужно указать ширину, чтобы правильно сгенерировались картинки х1.5\nесли не подходит, то используйте миксин из ui/Picture/Picture.astro\nгенерация и оптимизация картинок через gulp webp, gulp optimize\n\n```Astro\n---\nimport { Picture } from \"astro:assets\";\nimport myImage from \"@img/my-image.jpg\";\n---\n\n\u003cPicture\n  src={myImage}\n  alt=\"example image\"\n  quality={\"high\"}\n  formats={[\"webp\"]}\n  width={image.width / 2}\n  height={image.height / 2}\n  densities={[2]}\n/\u003e\n```\n\n**⚠️ Если вы используете исходные `png` картинки или преобразовываете через `fallbackFormat=\"png\"` (а так же динамическое использование `fallbackFormat=myImage.format`)\nделайте в компоненте проверку как ниже т.к. `squooshImageService` который используется в оптимизации картинок, не умеет оптимизировать png.**\n\n```Astro\n---\nimport myImagePng from \"@img/my-image-png.png\";\n---\n\n\u003cPicture\n  ...\n  quality={myImage.format === \"png\" ? null : \"high\"}\n  ...\n/\u003e\n```\n\n**Оптимизируйте `png` исходники вручную через [tinypng](https://tinypng.com/).**\n\n## Картинки из public folder\n\n```html\n\u003cimg src=\"./img/mountain-min.jpg\" width=\"320\" height=\"213\" alt=\"image\" /\u003e\n```\n\n## Картинки в стилях из public folder\n\n```css\nbackground-image: url('/img/mountain-min.jpg');\n```\n\n# Lenis is a lightweight, robust, and performant smooth scroll library.\n\nhttps://github.com/darkroomengineering/lenis\n\njs библиотека для плавной прокрутки\n\nхорошо работает вместе с gsap - библиотекой для анимации, обязательно подключить стили и базовые js настройки.\nФайл стилей лежит в папке 'src/styles/vendors/lenis.scss'\n\n```js\nimport { gsap } from 'gsap';\nimport { ScrollTrigger } from 'gsap/ScrollTrigger';\nimport Lenis from 'lenis';\n\ngsap.registerPlugin(ScrollTrigger);\n\nexport const lenis = new Lenis();\n\nlenis.on('scroll', ScrollTrigger.update);\n\ngsap.ticker.add((time) =\u003e {\n  lenis.raf(time * 1000);\n});\n\ngsap.ticker.lagSmoothing(0);\n```\n\nLenis - имеет фунцкцию scrollTo(target), подробнее в доке.\nПример, клик по якорным ссылкам, имортирую уже инициализоварнный класс lenis из index.js файла\n\n```js\nconst anchorLinks = document.querySelectorAll('[data-link]');\n// как вариант передать instance lenis в функцию при ее вызове\n// или эту фунцкию написать там где создается lenis и не передавать через параметр\nconst ininAcnhorLinks = (lenis) =\u003e {\n  if (anchorLinks) {\n    anchorLinks.forEach((link) =\u003e {\n      link.addEventListener('click', (evt) =\u003e {\n        evt.preventDefault();\n        const target = document.querySelector(`${link.getAttribute('href')}`);\n        if (!target) return;\n        lenis.scrollTo(target);\n      });\n    });\n  }\n};\nexport { ininAcnhorLinks };\n```\n\n### Баг с блокировкой скрола при использовании lenis\n\nПри использовании данной библиотеки для плавной прокрутки, просто навесив стили для body\n\n```css\n.scroll-lock {\n  overflow: hidden;\n}\n```\n\nне сработает, нужно блокировать сам lenis через js в те моменты где срабатывает блок скрола, например при открытии модального окна, добавив код ниже:\n\n```js\nlenis.isScrolling = false;\nlenis.isLocked = true;\nlenis.isStopped = true;\n```\n\nи разблокировать при закрытии модалки:\n\n```js\nlenis.isScrolling = false;\nlenis.isLocked = false;\nlenis.isStopped = false;\n```\n\nПри блокировки скрола, если нужно сохранить скролл во вложенном элементе, например при открытии бургер меню, в меню должна быть вертикальная прокрутка на не высоких (коротких) экранах - для этого элемента с прокрутой необходимо добавить атрибут:\n\n`data-lenis-prevent`\n\n\u003e как атрибут `data-scroll-lock-scrollable` при использовании библиотеки scroll-lock\n\n## Модальные окна\n\nНастроен базовый компонент модалки, со стилями и всем необходимым js кодом.\nСам class Modals находится тут `src/scripts/modules/modals/modals.js`.\nИспользует самописный класс для блокировки Фокуса, при открытии модалки, чтобы нельзя было навигировать с клавиатуры по элементам под модалкой.\nИспользуется npm пакет `scroll-lock` для блокировки скрола.\nНастроено закрытие модалки по клику на Ecs,вне модального окна и по клику на любой элемент внутри модалки с атрибутом `data-close-modal`\n\nastro компонент тут `src/components/Modal/Modal.astro`\nстили рядом `src/components/Modal/Modal.scss`\n\n### Пример использования ModalSuccess\n\n```js\n---\nimport Modal from '@components/Modal/Modal'\n\ninterface Props {}\n\nconst {} = Astro.props\n---\n\u003cModal name=\"success\" className=\"modal-success\"\u003e\n  \u003ch3 class=\"modal-success__title\"\u003eThank you!\u003c/h3\u003e\n  \u003cp class=\"modal-success__text\"\u003e\n    Our manager will contact you as soon as possible\n  \u003c/p\u003e\n  \u003cbutton\n    type=\"button\"\n    class=\"modal-success__close-button\"\n    data-close-modal\n  \u003e\n    Close modal\n  \u003c/button\u003e\n\u003c/Modal\u003e\n```\n\nМодалки подключаются в layout или отдельно на нужной странице.\nДля этого в layout есть именованный слот\n\n```html\n\u003cLayout title=\"{title}\" description=\"{description}\"\u003e\n  \u003cheader /\u003e\n  \u003cmain\u003e\n    \u003cslot /\u003e\n  \u003c/main\u003e\n  \u003cfooter /\u003e\n  \u003cslot name=\"modals\" /\u003e\n\u003c/Layout\u003e\n```\n\nЗатем на странице где используется данный layout прокидывается импортированный компонент модалки\n\n```html\n---\nimport Layout from '@layouts/layout'\nimport ModalSuccess from '@components/ModalSuccess/ModalSuccess'\n---\n\n\u003cLayout title=\"Главная\" description=\"Описание\"\u003e\n  \u003c!-- другие секции и компоненты--\u003e\n\n  \u003cFragment slot=\"modals\"\u003e\n    \u003cModalSuccess /\u003e\n  \u003c/Fragment\u003e\n\u003c/Layout\u003e\n```\n\nДля вызова модалки по клику на html элемент достаточно добавить на него атрибут с именем модалки `modal='success'`\n\n```html\n\u003cbutton type=\"button\" aria-label=\"открыть модалку\" modal=\"success\"\u003e\n  Modal Success\n\u003c/button\u003e\n```\n\nВ примерах есть еще модалка которая имеет прокрутку внутри, когда надо показать много контента, например, политику или какието правила. Для этого модалке надо установить атрибут `fixedHeight`\n`\u003cModal name=\"policy\" fixedHeight\u003e`\nэтим просто ограничивается по высоте блок .modal\\_\\_content и заданы стили для кастомного скролл бара.\n\n```html\n\u003cModal name=\"policy\" fixedHeight\u003e\n  \u003ch3\u003epolicy modal\u003c/h3\u003e\n  \u003cp\u003eс прокруткой\u003c/p\u003e\n  \u003cdiv class=\"modal__scroll-content\" data-scroll-lock-scrollable\u003e\n    \u003cp\u003e\n      Lorem ipsum dolor sit amet consectetur adipisicing elit. Doloremque\n      expedita tenetur...\n      \u003c!-- очень много контента--\u003e\n      asperiores quae perspiciatis aliquam animi aut, reiciendis sequi repellat\n      unde illum, consectetur ape\n    \u003c/p\u003e\n  \u003c/div\u003e\n\u003c/Modal\u003e\n```\n\n```css\n.modal--fixed-height {\n  .modal__content {\n    display: flex;\n    flex-direction: column;\n    max-height: 480px;\n    height: 100%;\n    width: 100%;\n    max-width: 1024px;\n  }\n\n  .modal__scroll-content {\n    display: flex;\n    overflow-y: auto;\n    max-height: 100%;\n    padding-right: 8px;\n\n    @include scroll-bar;\n  }\n}\n```\n\nДля стилизации скрол бара есть миксин `src/styles/global/mixins.scss`\n\n```scss\n@mixin scroll-bar {\n  \u0026::-webkit-scrollbar {\n    width: 12px;\n    height: 12px;\n  }\n\n  \u0026::-webkit-scrollbar-track {\n    // background-color: transparent;\n    background-color: green;\n    border-radius: 6px;\n  }\n\n  \u0026::-webkit-scrollbar-thumb {\n    background-color: rgba($color: red, $alpha: 0.6);\n    border-radius: 6px;\n  }\n\n  \u0026::-webkit-scrollbar-thumb:hover {\n    background-color: red;\n  }\n}\n```\n\n## ♠️ Иконки\n\nВсе иконки должны быть в папке `src/icons`.\nИспользуйте компонент Icon, он вставляет svg инлайном на страницу.\nСпрайт собирается автоматически при множественном использовании одной иконки на конкретной странице.\n\n```Astro\n---\nimport { Icon } from 'astro-icon/components'\n---\n\n\u003cdiv class=\"icon\"\u003e\n  \u003cIcon name=\"icon-close\" /\u003e\n\u003c/div\u003e\n```\n\nПодробнее узнать можно [тут](https://www.npmjs.com/package/astro-icon).\n\nНе используйте `\u003cimg\u003e` для этого кейса, если нужно использовать `svg` в тэге `\u003cimg\u003e`, добавляйте `svg` в папку `public/`.\n\n## 📦 Слоты \u003cslot\u003e\n\nПримеры использования можно посмотреть в [доке](https://docs.astro.build/en/core-concepts/astro-components/#slots), хотел лишь добавить что, если в вашем компоненте нужна проверка, принимает ли он слот или нет (например чтобы не генерировать лишнии пустые блоки которыми обернут слот) испрользуйте проверку 👇\n\n```Astro\n\u003cdiv class=\"card\"\u003e\n  ...\n  {Astro.slots.has(\"buttons\") \u0026\u0026 (\n    \u003cdiv class=\"card__buttons\"\u003e\n      \u003cslot name=\"buttons\"\u003e\n      \u003c/slot\u003e\n    \u003c/div\u003e\n  )}\n  ...\n\u003c/div\u003e\n```\n\nСлоты можно прокидывать через промежуточные компоненты: [пример из доки](https://docs.astro.build/en/core-concepts/astro-components/#transferring-slots)\n\n## 🧜 Полиморфные компоненты\n\nВ проекте есть полиморфные компоненты (Button) на основе пропса `as=\"...\"`, в который нужно передать желаемый `html` тэг. Это позволяет указать TS чтобы он подтянул нативные пропсы(аттрибуты) сам исходя из переданного тэга. Вы так же вы можете расширить TS-тип добавив нужные вам пропсы `type Props\u003cTag extends HTMLTag\u003e = Polymorphic\u003c{as: Tag}\u003e \u0026 { ..здесь ваши пропсы.. }`.\n\n## ⚙ Работа с экшенами\n\nДля работы экшенов при создании репозитория нужно обязательно в разделе `Actions =\u003e General` выбрать чекбокс \"Allow GitHub Actions to create and approve pull requests\" ([Скриншот](https://cln.sh/v99g2JdV)).\n\nДиректория dist добавлена в файл gitigonre. Для создания папки dist на проекте настроены экшены.\nДля работы с ними на сайте гитхаба необходимо зайти во вкладку **Actions** и выполнить следующие действия:\n\n1. Выбрать экшн, который нужно запустить. В сборке настроен экшен - Build, который собирает билд проекта в отдельную ветку `build`.\n2. Нажать на кнопку `Run workflow`. В выпадающем списке убедиться, что экшн будет запущен из ветки master и нажать зеленую кнопку `Run workflow`.\n3. После этого во вкладке Actions мы можем посмотреть на процесс выполнения нашего экшена. Когда экшн отработает корректно, напротив его названия появится зеленый значок, это означает что ошибок при его выполнении нет и он отработал корректно. После этого в списке веток репозитория должна появиться ветка `build`, в которой будет лежать наш собранный проект.\n\n## 🤖 Автоматический деплой на хост gitHub\n\nНужно подключить gitHub pages в настройках репозитория:\n`Settings =\u003e pages =\u003e Source =\u003e GitHub Pages`.\n\nАдрес хоста добавьте в информацию о репозитории (сверху справа на странице репозитория github).\nХост будет автоматически обновляться после заливки в мастер.\n\n## 👀 Хотите узнать больше?\n\nПосмотрите [документацию Astro](https://docs.astro.build).\n\nИспользуйте готовые компоненты из [Лиги решений](http://htmlonelove.top/liga-reshare/).\n\n## 🐱‍🐉 Проблемы и предложения по сборке\n\nПрисылайте свои [issues](https://github.com/htmlonelove/liga-astro-template/issues) в gitHub репозиторий\n\n### bugs\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faskomarov%2Fsound-buttons","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faskomarov%2Fsound-buttons","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faskomarov%2Fsound-buttons/lists"}