├── .editorconfig ├── .github ├── CONTRIBUTING.md ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── config.yml ├── auto-build-maybe.yml.txt ├── logo-dark.svg ├── logo-light.svg └── workflows │ └── BuildCSS.yml ├── .gitignore ├── .node-version ├── .nvmrc ├── .prettierrc ├── LICENSE.md ├── README.md ├── composer.json ├── css ├── pico.amber.css ├── pico.amber.min.css ├── pico.azure.css ├── pico.azure.min.css ├── pico.blue.css ├── pico.blue.min.css ├── pico.classless.amber.css ├── pico.classless.amber.min.css ├── pico.classless.azure.css ├── pico.classless.azure.min.css ├── pico.classless.blue.css ├── pico.classless.blue.min.css ├── pico.classless.conditional.amber.css ├── pico.classless.conditional.amber.min.css ├── pico.classless.conditional.azure.css ├── pico.classless.conditional.azure.min.css ├── pico.classless.conditional.blue.css ├── pico.classless.conditional.blue.min.css ├── pico.classless.conditional.cyan.css ├── pico.classless.conditional.cyan.min.css ├── pico.classless.conditional.fuchsia.css ├── pico.classless.conditional.fuchsia.min.css ├── pico.classless.conditional.green.css ├── pico.classless.conditional.green.min.css ├── pico.classless.conditional.grey.css ├── pico.classless.conditional.grey.min.css ├── pico.classless.conditional.indigo.css ├── pico.classless.conditional.indigo.min.css ├── pico.classless.conditional.jade.css ├── pico.classless.conditional.jade.min.css ├── pico.classless.conditional.lime.css ├── pico.classless.conditional.lime.min.css ├── pico.classless.conditional.orange.css ├── pico.classless.conditional.orange.min.css ├── pico.classless.conditional.pink.css ├── pico.classless.conditional.pink.min.css ├── pico.classless.conditional.pumpkin.css ├── pico.classless.conditional.pumpkin.min.css ├── pico.classless.conditional.purple.css ├── pico.classless.conditional.purple.min.css ├── pico.classless.conditional.red.css ├── pico.classless.conditional.red.min.css ├── pico.classless.conditional.sand.css ├── pico.classless.conditional.sand.min.css ├── pico.classless.conditional.slate.css ├── pico.classless.conditional.slate.min.css ├── pico.classless.conditional.violet.css ├── pico.classless.conditional.violet.min.css ├── pico.classless.conditional.yellow.css ├── pico.classless.conditional.yellow.min.css ├── pico.classless.conditional.zinc.css ├── pico.classless.conditional.zinc.min.css ├── pico.classless.css ├── pico.classless.cyan.css ├── pico.classless.cyan.min.css ├── pico.classless.fuchsia.css ├── pico.classless.fuchsia.min.css ├── pico.classless.green.css ├── pico.classless.green.min.css ├── pico.classless.grey.css ├── pico.classless.grey.min.css ├── pico.classless.indigo.css ├── pico.classless.indigo.min.css ├── pico.classless.jade.css ├── pico.classless.jade.min.css ├── pico.classless.lime.css ├── pico.classless.lime.min.css ├── pico.classless.min.css ├── pico.classless.orange.css ├── pico.classless.orange.min.css ├── pico.classless.pink.css ├── pico.classless.pink.min.css ├── pico.classless.pumpkin.css ├── pico.classless.pumpkin.min.css ├── pico.classless.purple.css ├── pico.classless.purple.min.css ├── pico.classless.red.css ├── pico.classless.red.min.css ├── pico.classless.sand.css ├── pico.classless.sand.min.css ├── pico.classless.slate.css ├── pico.classless.slate.min.css ├── pico.classless.violet.css ├── pico.classless.violet.min.css ├── pico.classless.yellow.css ├── pico.classless.yellow.min.css ├── pico.classless.zinc.css ├── pico.classless.zinc.min.css ├── pico.colors.css ├── pico.colors.min.css ├── pico.conditional.amber.css ├── pico.conditional.amber.min.css ├── pico.conditional.azure.css ├── pico.conditional.azure.min.css ├── pico.conditional.blue.css ├── pico.conditional.blue.min.css ├── pico.conditional.css ├── pico.conditional.cyan.css ├── pico.conditional.cyan.min.css ├── pico.conditional.fuchsia.css ├── pico.conditional.fuchsia.min.css ├── pico.conditional.green.css ├── pico.conditional.green.min.css ├── pico.conditional.grey.css ├── pico.conditional.grey.min.css ├── pico.conditional.indigo.css ├── pico.conditional.indigo.min.css ├── pico.conditional.jade.css ├── pico.conditional.jade.min.css ├── pico.conditional.lime.css ├── pico.conditional.lime.min.css ├── pico.conditional.min.css ├── pico.conditional.orange.css ├── pico.conditional.orange.min.css ├── pico.conditional.pink.css ├── pico.conditional.pink.min.css ├── pico.conditional.pumpkin.css ├── pico.conditional.pumpkin.min.css ├── pico.conditional.purple.css ├── pico.conditional.purple.min.css ├── pico.conditional.red.css ├── pico.conditional.red.min.css ├── pico.conditional.sand.css ├── pico.conditional.sand.min.css ├── pico.conditional.slate.css ├── pico.conditional.slate.min.css ├── pico.conditional.violet.css ├── pico.conditional.violet.min.css ├── pico.conditional.yellow.css ├── pico.conditional.yellow.min.css ├── pico.conditional.zinc.css ├── pico.conditional.zinc.min.css ├── pico.css ├── pico.cyan.css ├── pico.cyan.min.css ├── pico.fluid.classless.amber.css ├── pico.fluid.classless.amber.min.css ├── pico.fluid.classless.azure.css ├── pico.fluid.classless.azure.min.css ├── pico.fluid.classless.blue.css ├── pico.fluid.classless.blue.min.css ├── pico.fluid.classless.conditional.amber.css ├── pico.fluid.classless.conditional.amber.min.css ├── pico.fluid.classless.conditional.azure.css ├── pico.fluid.classless.conditional.azure.min.css ├── pico.fluid.classless.conditional.blue.css ├── pico.fluid.classless.conditional.blue.min.css ├── pico.fluid.classless.conditional.css ├── pico.fluid.classless.conditional.cyan.css ├── pico.fluid.classless.conditional.cyan.min.css ├── pico.fluid.classless.conditional.fuchsia.css ├── pico.fluid.classless.conditional.fuchsia.min.css ├── pico.fluid.classless.conditional.green.css ├── pico.fluid.classless.conditional.green.min.css ├── pico.fluid.classless.conditional.grey.css ├── pico.fluid.classless.conditional.grey.min.css ├── pico.fluid.classless.conditional.indigo.css ├── pico.fluid.classless.conditional.indigo.min.css ├── pico.fluid.classless.conditional.jade.css ├── pico.fluid.classless.conditional.jade.min.css ├── pico.fluid.classless.conditional.lime.css ├── pico.fluid.classless.conditional.lime.min.css ├── pico.fluid.classless.conditional.min.css ├── pico.fluid.classless.conditional.orange.css ├── pico.fluid.classless.conditional.orange.min.css ├── pico.fluid.classless.conditional.pink.css ├── pico.fluid.classless.conditional.pink.min.css ├── pico.fluid.classless.conditional.pumpkin.css ├── pico.fluid.classless.conditional.pumpkin.min.css ├── pico.fluid.classless.conditional.purple.css ├── pico.fluid.classless.conditional.purple.min.css ├── pico.fluid.classless.conditional.red.css ├── pico.fluid.classless.conditional.red.min.css ├── pico.fluid.classless.conditional.sand.css ├── pico.fluid.classless.conditional.sand.min.css ├── pico.fluid.classless.conditional.slate.css ├── pico.fluid.classless.conditional.slate.min.css ├── pico.fluid.classless.conditional.violet.css ├── pico.fluid.classless.conditional.violet.min.css ├── pico.fluid.classless.conditional.yellow.css ├── pico.fluid.classless.conditional.yellow.min.css ├── pico.fluid.classless.conditional.zinc.css ├── pico.fluid.classless.conditional.zinc.min.css ├── pico.fluid.classless.css ├── pico.fluid.classless.cyan.css ├── pico.fluid.classless.cyan.min.css ├── pico.fluid.classless.fuchsia.css ├── pico.fluid.classless.fuchsia.min.css ├── pico.fluid.classless.green.css ├── pico.fluid.classless.green.min.css ├── pico.fluid.classless.grey.css ├── pico.fluid.classless.grey.min.css ├── pico.fluid.classless.indigo.css ├── pico.fluid.classless.indigo.min.css ├── pico.fluid.classless.jade.css ├── pico.fluid.classless.jade.min.css ├── pico.fluid.classless.lime.css ├── pico.fluid.classless.lime.min.css ├── pico.fluid.classless.min.css ├── pico.fluid.classless.orange.css ├── pico.fluid.classless.orange.min.css ├── pico.fluid.classless.pink.css ├── pico.fluid.classless.pink.min.css ├── pico.fluid.classless.pumpkin.css ├── pico.fluid.classless.pumpkin.min.css ├── pico.fluid.classless.purple.css ├── pico.fluid.classless.purple.min.css ├── pico.fluid.classless.red.css ├── pico.fluid.classless.red.min.css ├── pico.fluid.classless.sand.css ├── pico.fluid.classless.sand.min.css ├── pico.fluid.classless.slate.css ├── pico.fluid.classless.slate.min.css ├── pico.fluid.classless.violet.css ├── pico.fluid.classless.violet.min.css ├── pico.fluid.classless.yellow.css ├── pico.fluid.classless.yellow.min.css ├── pico.fluid.classless.zinc.css ├── pico.fluid.classless.zinc.min.css ├── pico.fuchsia.css ├── pico.fuchsia.min.css ├── pico.green.css ├── pico.green.min.css ├── pico.grey.css ├── pico.grey.min.css ├── pico.indigo.css ├── pico.indigo.min.css ├── pico.jade.css ├── pico.jade.min.css ├── pico.lime.css ├── pico.lime.min.css ├── pico.min.css ├── pico.orange.css ├── pico.orange.min.css ├── pico.pink.css ├── pico.pink.min.css ├── pico.pumpkin.css ├── pico.pumpkin.min.css ├── pico.purple.css ├── pico.purple.min.css ├── pico.red.css ├── pico.red.min.css ├── pico.sand.css ├── pico.sand.min.css ├── pico.slate.css ├── pico.slate.min.css ├── pico.violet.css ├── pico.violet.min.css ├── pico.yellow.css ├── pico.yellow.min.css ├── pico.zinc.css ├── pico.zinc.min.css └── postcss.config.js ├── docs ├── .editorconfig ├── basics.css ├── favicon-152x152.png ├── favicon-167x167.png ├── favicon-16x16.png ├── favicon-180x180.png ├── favicon-192x192.png ├── favicon-32x32.png ├── favicon-48x48.png ├── favicon-512x512.png ├── favicon.ico ├── favicon.svg ├── index.html ├── js │ ├── FileValidator.js │ ├── Modal.js │ ├── PicoTabs.js │ ├── SwitchColorMode.js │ └── old │ │ └── MinimalThemeSwitcher.js ├── manifest.json ├── pico.colors.min.css ├── pico.css └── pico.min.css ├── package.json ├── scripts ├── build-dev.js ├── build-themes.js ├── copy-docs-css-files-dev.js └── copy-docs-css-files.js └── scss ├── _index.scss ├── _settings.scss ├── colors ├── _index.scss └── utilities │ ├── _background-colors.scss │ ├── _colors.scss │ ├── _css-vars.scss │ ├── _index.scss │ ├── _settings.scss │ └── _utils.scss ├── components ├── _accordion.scss ├── _card.scss ├── _dropdown.scss ├── _group.scss ├── _loading.scss ├── _modal.scss ├── _nav-hamburger.scss ├── _nav.scss ├── _notification.scss ├── _popover-toast.scss ├── _popover.scss ├── _progress.scss ├── _tab-region.scss ├── _tab.scss ├── _timeline.scss └── _tooltip.scss ├── content ├── _button.scss ├── _code.scss ├── _embedded.scss ├── _figure.scss ├── _link.scss ├── _misc.scss ├── _table.scss └── _typography.scss ├── forms ├── _basics.scss ├── _checkbox-radio-switch.scss ├── _floating.scss ├── _input-color.scss ├── _input-date.scss ├── _input-file.scss ├── _input-range.scss ├── _input-search.scss └── _validation.scss ├── helpers ├── _copyright.scss └── _functions.scss ├── layout ├── _container.scss ├── _document.scss ├── _grid.scss ├── _landmarks.scss ├── _overflow-auto.scss ├── _row.scss └── _section.scss ├── pico.classless.scss ├── pico.colors.scss ├── pico.conditional.scss ├── pico.fluid.classless.conditional.scss ├── pico.fluid.classless.scss ├── pico.scss ├── postcss.config.js ├── themes ├── _default.scss └── default │ ├── _dark.scss │ ├── _light.scss │ ├── _schemes.scss │ ├── _styles.scss │ └── _theme-colors.scss └── utilities ├── _accessibility.scss └── _reduce-motion.scss /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: https://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | # Unix-style newlines with a newline ending every file 7 | [*] 8 | end_of_line = crlf 9 | insert_final_newline = true 10 | charset = utf-8 11 | trim_trailing_whitespace = true 12 | indent_style = space 13 | indent_size = 2 14 | 15 | # JavaScript and JSON files 16 | [*.{js,json}] 17 | indent_size = 2 18 | 19 | # SCSS files 20 | [*.scss] 21 | indent_size = 2 22 | 23 | # Markdown files 24 | [*.md] 25 | trim_trailing_whitespace = false 26 | 27 | # Package files 28 | [package.json] 29 | indent_size = 2 30 | 31 | # Config files 32 | [*.{yml,yaml}] 33 | indent_size = 2 34 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Pico 2 | 3 | Thanks for your interest in contributing to Pico CSS! Please take a moment to review this document before submitting a [bug report](https://github.com/Yohn/PicoCSS/issues) or a [pull request](https://github.com/Yohn/PicoCSS/pulls). 4 | 5 | ## Bug reports 6 | 7 | The [issue tracker]((https://github.com/Yohn/PicoCSS/issues)) is the preferred channel for bug reports, but please respect the following restrictions: 8 | - Please do not use the issue tracker for personal support requests. [Open a question in our discussion forums](https://github.com/Yohn/PicoCSS/discussions/categories/help) instead. 9 | - Please do not use the issue tracker for feature requests. Instead, use our discussion forums to [suggest any ideas](https://github.com/Yohn/PicoCSS/discussions/categories/ideas) you have. 10 | 11 | ## Pull requests 12 | 13 | Good pull requests, patches, improvements, and new features are a fantastic help. 14 | 15 | **Please ask before starting work on any significant new features.** 16 | We recommend that you first [suggest your feature idea in our discussion forums](https://github.com/Yohn/PicoCSS/discussions/categories/ideas). 17 | 18 | 21 | 22 | **Do not edit [`/css`](https://github.com/Yohn/PicoCSS/tree/master/css) files directly.** 23 | 24 | Edit the source files in [`/scss`](https://github.com/Yohn/PicoCSS/tree/master/scss), Github will automatically re-compile the css files after the pull request is merged. 25 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [Yohn] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | #patreon: # Replace with a single Patreon username 5 | #open_collective: # Replace with a single Open Collective username 6 | #ko_fi: # Replace with a single Ko-fi username 7 | #tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | #community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | #liberapay: # Replace with a single Liberapay username 10 | #issuehunt: # Replace with a single IssueHunt username 11 | #lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 12 | #polar: # Replace with a single Polar username 13 | #buy_me_a_coffee: # Replace with a single Buy Me a Coffee username 14 | #thanks_dev: # Replace with a single thanks.dev username 15 | custom: ['http://cash.me/$yohnjohn84'] # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 16 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a bug report if you've already asked for help with a problem and confirmed something is broken with Pico CSS. 4 | --- 5 | 6 | Please search for duplicate or closed issues first. 7 | 8 | ## Describe the issue 9 | 10 | ### Current Behavior 11 | A concise description of the bug. 12 | 13 | ### Expected Behavior 14 | A concise description of what you expected. 15 | 16 | ### Reproduction URL 17 | We recommend including a link to a minimal reproduction of the bug using CodePen or a similar tool. 18 | **Please do not link to your actual project.** Instead, we need a reduced test case in a new project without any unnecessary code. 19 | 20 | ### Environment 21 | Example: OS, versions, browser details. 22 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Get Help 4 | url: https://github.com/Yohn/PicoCSS/discussions/categories/help 5 | about: If you can't get something to work the way you expect, open a question in our discussion forums. 6 | - name: Feature Request 7 | url: https://github.com/Yohn/PicoCSS/discussions/categories/ideas 8 | about: Suggest any ideas you have using our discussion forums. 9 | -------------------------------------------------------------------------------- /.github/auto-build-maybe.yml.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.github/logo-dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /.github/logo-light.svg: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /.github/workflows/BuildCSS.yml: -------------------------------------------------------------------------------- 1 | name: Build CSS 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths: 8 | - 'scss/**' 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | 14 | permissions: 15 | contents: write 16 | 17 | steps: 18 | - name: Checkout repository 19 | uses: actions/checkout@v2 20 | 21 | - name: Set up Node.js 22 | uses: actions/setup-node@v2 23 | with: 24 | node-version: '20' 25 | 26 | - name: Install dependencies 27 | run: npm install 28 | 29 | - name: Build CSS 30 | run: npm run build 31 | 32 | - name: Commit and push changes 33 | run: | 34 | git config --global user.name 'github-actions[bot]' 35 | git config --global user.email 'github-actions[bot]@users.noreply.github.com' 36 | git add . 37 | git commit -m 'Build CSS' 38 | git push 39 | env: 40 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OS or Editor folders 2 | ._* 3 | .cache 4 | .DS_Store 5 | .idea 6 | .project 7 | .settings 8 | .tmproj 9 | *.esproj 10 | *.sublime-project 11 | *.sublime-workspace 12 | nbproject 13 | Thumbs.db 14 | /.vscode/ 15 | 16 | # Numerous always-ignore extensions 17 | *.diff 18 | *.err 19 | *.log 20 | *.orig 21 | *.rej 22 | *.swo 23 | *.swp 24 | *.vi 25 | *.zip 26 | *~ 27 | 28 | # Folders to ignore 29 | /node_modules/ 30 | 31 | # Pico 32 | .pico 33 | package-lock.json 34 | /docs/orig 35 | /scss/components/_offcanvas.scss 36 | docs/js/DialogManager.js 37 | docs/modal.html 38 | 39 | /.yohn 40 | _docs/ 41 | 42 | /zzz -------------------------------------------------------------------------------- /.node-version: -------------------------------------------------------------------------------- 1 | 20 -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 20 -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 100 3 | } 4 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019-2024 Pico 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 |

2 | 3 | 4 | 5 | 6 | Pico CSS 7 | 8 | 9 |

10 | 11 | [![Github release](https://img.shields.io/github/v/release/Yohn/PicoCSS?color=0172.ad&logo=github&logoColor=white)](https://github.com/Yohn/PicoCSS/releases/latest) 12 | [![npm version](https://img.shields.io/npm/v/@yohns/picocss?color=0172ad)](https://www.npmjs.com/package/@yohns/picocss) 13 | [![License](https://img.shields.io/badge/license-MIT-%230172ad)](https://github.com/Yohn/PicoCSS/blob/master/LICENSE.md) 14 | 15 | 16 | ## Yohns Updated Version 17 | I'm not sure if the original [Pico CSS](https://github.com/picocss/pico) repository is abandoned or not, but I really liked what they had to offer, and wanted to help not let this awesomely simple and easy to use front end framework disappear, so I merged as many of open pull requests that fixed some issues, and / or enhanced the project that were available at the time. I'll try to help keep it viable and do some bug fixes if any arise, and would always appreciate anyone elses help to continue keeping this alive! 18 | 19 | You can see the new features I, and many others have created pull requests for by going to [Yohns Pico CSS](https://yohn.github.io/PicoCSS). This page just has the demos of most of the features I have merged, or added to the project. 20 | 21 | ## Extras Built on top of PicoCSS 22 | - [Alert, Confirm, and Prompt Dialogs](https://github.com/Yohn/PicoCSS-Datatables/blob/main/src/CustomDialog.js) (Will work on that more later, but it works good!) 23 | - [YoSelect](https://github.com/Yohn/YoSelect) Searchable ` 149 | // const fileInput = document.getElementById("fileInput"); 150 | // new FileValidator(fileInput, false); // Hide display list 151 | // 152 | // Alternatively, with custom list container: 153 | // const customListContainer = document.getElementById("customListContainer"); 154 | // new FileValidator(fileInput, true, customListContainer); 155 | 156 | // Usage example2: 157 | // 158 | // 1048576 = 1MB 159 | // const checkfile = document.getElementById("checkfile"); 160 | // new FileValidator(checkfile); 161 | -------------------------------------------------------------------------------- /docs/js/Modal.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Modal 3 | * 4 | * Pico.css - https://picocss.com 5 | * Copyright 2019-2025 - Licensed under MIT 6 | * Modified by Yohn https://github.com/Yohn/PicoCSS 7 | */ 8 | //document.addEventListener("DOMContentLoaded", () => { 9 | // Config 10 | const isOpenClass = "modal-is-open"; 11 | const openingClass = "modal-is-opening"; 12 | const closingClass = "modal-is-closing"; 13 | const scrollbarWidthCssVar = "--pico-scrollbar-width"; 14 | const animationDuration = 400; // ms 15 | let visibleModal = null; 16 | 17 | // Toggle modal 18 | const toggleModal = (event) => { 19 | event.preventDefault(); 20 | const modal = document.getElementById(event.currentTarget.dataset.target); 21 | if (!modal) return; 22 | if(event.currentTarget.dataset.close) { 23 | const modalClose = document.getElementById(event.currentTarget.dataset.close); 24 | if(modalClose){ 25 | closeModal(modalClose); 26 | setTimeout(() => modal && (modal.open ? closeModal(modal) : openModal(modal)), animationDuration); 27 | } 28 | } else { 29 | modal && (modal.open ? closeModal(modal) : openModal(modal)); 30 | } 31 | }; 32 | 33 | // Open modal 34 | const openModal = (modal) => { 35 | const { documentElement: html } = document; 36 | const scrollbarWidth = getScrollbarWidth(); 37 | if (scrollbarWidth) { 38 | html.style.setProperty(scrollbarWidthCssVar, `${scrollbarWidth}px`); 39 | } 40 | html.classList.add(isOpenClass, openingClass); 41 | setTimeout(() => { 42 | visibleModal = modal; 43 | html.classList.remove(openingClass); 44 | }, animationDuration); 45 | modal.showModal(); 46 | }; 47 | 48 | // Close modal 49 | const closeModal = (modal) => { 50 | visibleModal = null; 51 | const { documentElement: html } = document; 52 | html.classList.add(closingClass); 53 | setTimeout(() => { 54 | html.classList.remove(closingClass, isOpenClass); 55 | html.style.removeProperty(scrollbarWidthCssVar); 56 | modal.close(); 57 | }, animationDuration); 58 | }; 59 | 60 | // Close with a click outside 61 | document.addEventListener("click", (event) => { 62 | if (visibleModal === null) return; 63 | const modalContent = visibleModal.querySelector("article"); 64 | const isClickInside = modalContent.contains(event.target); 65 | !isClickInside && closeModal(visibleModal); 66 | }); 67 | 68 | // Close with Esc key 69 | document.addEventListener("keydown", (event) => { 70 | if (event.key === "Escape" && visibleModal) { 71 | closeModal(visibleModal); 72 | } 73 | }); 74 | 75 | // Get scrollbar width 76 | const getScrollbarWidth = () => { 77 | const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth; 78 | return scrollbarWidth; 79 | }; 80 | 81 | // Is scrollbar visible 82 | const isScrollbarVisible = () => { 83 | return document.body.scrollHeight > screen.height; 84 | }; 85 | //}) 86 | -------------------------------------------------------------------------------- /docs/js/PicoTabs.js: -------------------------------------------------------------------------------- 1 | /* 2 | // To not have any keypresses change the tabs use the following 3 | document.addEventListener("DOMContentLoaded", () => { 4 | const tabs = document.querySelectorAll('[role="tab"]'); 5 | const panels = document.querySelectorAll('[role="tabpanel"]'); 6 | 7 | tabs.forEach((tab, index) => { 8 | tab.addEventListener("click", () => { 9 | // Reset all tabs and panels 10 | tabs.forEach((t, i) => { 11 | t.setAttribute("aria-selected", "false"); 12 | t.setAttribute("tabindex", "-1"); 13 | panels[i].setAttribute("hidden", true); 14 | }); 15 | 16 | // Activate the clicked tab 17 | tab.setAttribute("aria-selected", "true"); 18 | tab.setAttribute("tabindex", "0"); 19 | document 20 | .querySelector('[aria-labelledby="' + tab.id + '"]') 21 | .removeAttribute("hidden"); 22 | 23 | // Focus the activated tab 24 | tab.focus(); 25 | }); 26 | }); 27 | }); 28 | */ 29 | 30 | class PicoTabs { 31 | constructor(tabListContainerSelector) { 32 | this.tabLists = document.querySelectorAll(tabListContainerSelector); 33 | 34 | // Proceed only if tablists are found 35 | if (this.tabLists.length === 0) { 36 | console.warn(`No elements with ${tabListContainerSelector} found on the page.`); 37 | return; 38 | } 39 | 40 | this.tabLists.forEach((tabList) => { 41 | const tabs = Array.from(tabList.querySelectorAll('[role="tab"]')); 42 | const panels = Array.from(tabList.querySelectorAll('[role="tabpanel"]')); 43 | 44 | // Filter out nested tabs and panels 45 | const rootTabs = tabs.filter((tab) => tab.closest(tabListContainerSelector) === tabList); 46 | const rootPanels = panels.filter((panel) => panel.closest(tabListContainerSelector) === tabList); 47 | 48 | // Proceed only if root tabs and panels are found 49 | if (rootTabs.length === 0 || rootPanels.length === 0) { 50 | console.warn("No root tabs or panels found in a tablist, skipping initialization."); 51 | return; 52 | } 53 | 54 | this.init(tabList, rootTabs, rootPanels); 55 | }); 56 | } 57 | 58 | init(tabList, tabs, panels) { 59 | tabs.forEach((tab, index) => { 60 | tab.addEventListener("click", () => this.activateTab(tabs, panels, index)); 61 | tab.addEventListener("keydown", (e) => this.handleKeyDown(e, tabs, panels, index)); 62 | }); 63 | } 64 | 65 | // Activate a tab and corresponding panel 66 | activateTab(tabs, panels, index) { 67 | // Reset all tabs and panels within the current tablist 68 | tabs.forEach((tab, i) => { 69 | tab.setAttribute("aria-selected", "false"); 70 | tab.setAttribute("tabindex", "-1"); 71 | panels[i].setAttribute("hidden", "true"); 72 | }); 73 | 74 | // Activate the specified tab 75 | tabs[index].setAttribute("aria-selected", "true"); 76 | tabs[index].setAttribute("tabindex", "0"); 77 | panels[index].removeAttribute("hidden"); 78 | 79 | // Focus the activated tab 80 | tabs[index].focus(); 81 | } 82 | 83 | // Handle keyboard navigation 84 | handleKeyDown(event, tabs, panels, currentIndex) { 85 | switch (event.key) { 86 | case "ArrowLeft": 87 | event.preventDefault(); 88 | this.activateTab(tabs, panels, (currentIndex - 1 + tabs.length) % tabs.length); 89 | break; 90 | case "ArrowRight": 91 | event.preventDefault(); 92 | this.activateTab(tabs, panels, (currentIndex + 1) % tabs.length); 93 | break; 94 | case "Home": 95 | event.preventDefault(); 96 | this.activateTab(tabs, panels, 0); 97 | break; 98 | case "End": 99 | event.preventDefault(); 100 | this.activateTab(tabs, panels, tabs.length - 1); 101 | break; 102 | default: 103 | break; 104 | } 105 | } 106 | } 107 | 108 | //document.addEventListener("DOMContentLoaded", () => { 109 | // new PicoTabs('[role="tablist"]'); 110 | //}); 111 | -------------------------------------------------------------------------------- /docs/js/SwitchColorMode.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Minimal theme switcher using a checkbox 3 | * 4 | * Pico.css - https://picocss.com 5 | * Copyright 2019-2025 - Licensed under MIT 6 | * Modified by Yohn https://github.com/Yohn/PicoCSS 7 | */ 8 | 9 | const SwitchColorMode = { 10 | // Config 11 | _scheme: "auto", 12 | toggleSelector: "input[name='color-mode-toggle']", 13 | rootAttribute: "data-theme", 14 | localStorageKey: "picoPreferredColorScheme", 15 | 16 | // Init 17 | init() { 18 | this.checkbox = document.querySelector(this.toggleSelector); 19 | if (!this.checkbox) { 20 | console.error("Theme switcher toggle not found"); 21 | return; 22 | } 23 | 24 | // If first visit, use the theme from attribute; otherwise, use stored preference 25 | this.scheme = this.schemeFromLocalStorage ?? this.schemeFromHTML; 26 | 27 | // Set checkbox state based on the applied theme 28 | this.checkbox.checked = this.scheme === "dark"; 29 | 30 | // Listen for user changes 31 | this.checkbox.addEventListener("change", () => { 32 | this.scheme = this.checkbox.checked ? "dark" : "light"; 33 | this.schemeToLocalStorage(); 34 | }); 35 | }, 36 | 37 | // Get color scheme from local storage 38 | get schemeFromLocalStorage() { 39 | return window.localStorage?.getItem(this.localStorageKey); 40 | }, 41 | 42 | // Get the default theme from the attribute 43 | get schemeFromHTML() { 44 | return document.documentElement.getAttribute(this.rootAttribute) ?? "auto"; 45 | }, 46 | 47 | // Preferred color scheme from system 48 | get preferredColorScheme() { 49 | return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"; 50 | }, 51 | 52 | // Set scheme 53 | set scheme(scheme) { 54 | if (scheme === "auto") { 55 | this._scheme = this.preferredColorScheme; 56 | } else if (scheme === "dark" || scheme === "light") { 57 | this._scheme = scheme; 58 | } 59 | this.applyScheme(); 60 | }, 61 | 62 | // Get scheme 63 | get scheme() { 64 | return this._scheme; 65 | }, 66 | 67 | // Apply scheme 68 | applyScheme() { 69 | document.documentElement.setAttribute(this.rootAttribute, this._scheme); 70 | }, 71 | 72 | // Store scheme to local storage 73 | schemeToLocalStorage() { 74 | window.localStorage?.setItem(this.localStorageKey, this.scheme); 75 | }, 76 | }; 77 | 78 | // Init 79 | SwitchColorMode.init(); -------------------------------------------------------------------------------- /docs/js/old/MinimalThemeSwitcher.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Minimal theme switcher 3 | * 4 | * Pico.css - https://picocss.com 5 | * Copyright 2019-2024 - Licensed under MIT 6 | */ 7 | 8 | const themeSwitcher = { 9 | // Config 10 | _scheme: "auto", 11 | menuTarget: "details.dropdown", 12 | buttonsTarget: "a[data-theme-switcher]", 13 | buttonAttribute: "data-theme-switcher", 14 | rootAttribute: "data-theme", 15 | localStorageKey: "picoPreferredColorScheme", 16 | 17 | // Init 18 | init() { 19 | this.scheme = this.schemeFromLocalStorage; 20 | this.initSwitchers(); 21 | }, 22 | 23 | // Get color scheme from local storage 24 | get schemeFromLocalStorage() { 25 | return window.localStorage?.getItem(this.localStorageKey) ?? this._scheme; 26 | }, 27 | 28 | // Preferred color scheme 29 | get preferredColorScheme() { 30 | return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"; 31 | }, 32 | 33 | // Init switchers 34 | initSwitchers() { 35 | const buttons = document.querySelectorAll(this.buttonsTarget); 36 | buttons.forEach((button) => { 37 | button.addEventListener( 38 | "click", 39 | (event) => { 40 | event.preventDefault(); 41 | // Set scheme 42 | this.scheme = button.getAttribute(this.buttonAttribute); 43 | // Close dropdown 44 | document.querySelector(this.menuTarget)?.removeAttribute("open"); 45 | }, 46 | false 47 | ); 48 | }); 49 | }, 50 | 51 | // Set scheme 52 | set scheme(scheme) { 53 | if (scheme == "auto") { 54 | this._scheme = this.preferredColorScheme; 55 | } else if (scheme == "dark" || scheme == "light") { 56 | this._scheme = scheme; 57 | } 58 | this.applyScheme(); 59 | this.schemeToLocalStorage(); 60 | }, 61 | 62 | // Get scheme 63 | get scheme() { 64 | return this._scheme; 65 | }, 66 | 67 | // Apply scheme 68 | applyScheme() { 69 | document.querySelector("html")?.setAttribute(this.rootAttribute, this.scheme); 70 | }, 71 | 72 | // Store scheme to local storage 73 | schemeToLocalStorage() { 74 | window.localStorage?.setItem(this.localStorageKey, this.scheme); 75 | }, 76 | }; 77 | 78 | // Init 79 | themeSwitcher.init(); 80 | -------------------------------------------------------------------------------- /docs/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Pico CSS", 3 | "name": "Pico CSS", 4 | "description": "A pure HTML example, without dependencies.", 5 | "icons": [ 6 | { 7 | "src": "favicon.ico", 8 | "sizes": "64x64 32x32 24x24 16x16", 9 | "type": "image/x-icon" 10 | }, 11 | { 12 | "src": "favicon-48x48.png", 13 | "type": "image/png", 14 | "sizes": "48x48" 15 | }, 16 | { 17 | "src": "favicon-192x192.png", 18 | "type": "image/png", 19 | "sizes": "192x192" 20 | }, 21 | { 22 | "src": "favicon-512x512.png", 23 | "type": "image/png", 24 | "sizes": "512x512" 25 | } 26 | ], 27 | "start_url": ".", 28 | "display": "standalone", 29 | "theme_color": "#000000", 30 | "background_color": "#ffffff" 31 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@yohns/picocss", 3 | "version": "2.2.10", 4 | "description": "Minimal CSS Framework for semantic HTML, updated with enhanced capabilities.", 5 | "authors": [ 6 | { 7 | "name": "Lucas Larroche", 8 | "website": "https://github.com/picocss/pico" 9 | }, 10 | { 11 | "name": "John Brittain III", 12 | "website": "https://github.com/Yohn/PicoCSS" 13 | } 14 | ], 15 | "main": "css/pico.min.css", 16 | "homepage": "https://picocss.com", 17 | "license": "MIT", 18 | "repository": { 19 | "type": "git", 20 | "url": "git+https://github.com/Yohn/PicoCSS.git" 21 | }, 22 | "keywords": [ 23 | "css", 24 | "css-framework", 25 | "dark-mode", 26 | "dark-theme", 27 | "lightweight", 28 | "minimal", 29 | "minimalist", 30 | "minimalistic", 31 | "native-html", 32 | "scss-framework", 33 | "semantic" 34 | ], 35 | "bugs": { 36 | "url": "https://github.com/Yohn/PicoCSS/issues" 37 | }, 38 | "scripts": { 39 | "✨": "run-s build", 40 | "build": "run-s start lint \"build:*\" done --silent", 41 | "build-dev": "run-s start lint \"build-dev:*\" done --silent", 42 | "dev": "nodemon -q --watch scss/ --ext scss --exec \"run-s build-dev\"", 43 | "lint": "run-s \"lint:*\" --silent", 44 | "lint:prettier": "prettier --write --log-level error \"scss/**/*.scss\"", 45 | "lint:sort-scss": "postcss --config scss ./scss/**/*.scss --replace", 46 | "build-dev:css": "sass --no-source-map --style expanded --no-error-css scss/:css/", 47 | "build:css": "sass --no-source-map --style expanded --no-error-css scss/:css/", 48 | "build-dev:themes": "node scripts/build-dev", 49 | "build:themes": "node scripts/build-themes", 50 | "build-dev:autoprefix": "postcss --config css --replace css/*.css !css/*.min.css", 51 | "build:autoprefix": "postcss --config css --replace css/*.css !css/*.min.css", 52 | "build-dev:minify": "cleancss -O1 --with-rebase --batch --batch-suffix .min css/*.css !css/*.min.css", 53 | "build:minify": "cleancss -O1 --with-rebase --batch --batch-suffix .min css/*.css !css/*.min.css", 54 | "build-dev:postbuild": "node scripts/copy-docs-css-files", 55 | "build:postbuild": "node scripts/copy-docs-css-files", 56 | "prelint": "echo '[@Yohns/PicoCSS] ✨ Lint'", 57 | "prebuild:css": "echo '[@Yohns/PicoCSS] ✨ Compile'", 58 | "prebuild:themes": "echo '[@Yohns/PicoCSS] ✨ Compile themes'", 59 | "prebuild:autoprefix": "echo '[@Yohns/PicoCSS] ✨ Autoprefix'", 60 | "prebuild:minify": "echo '[@Yohns/PicoCSS] ✨ Minify'", 61 | "start": "echo '\\033[96m[@Yohns/PicoCSS] ✨ Start\\033[0m'", 62 | "done": "echo '\\033[32m[@Yohns/PicoCSS] ✨ Done\\033[0m'" 63 | }, 64 | "devDependencies": { 65 | "autoprefixer": "^10.4.20", 66 | "caniuse-lite": "^1.0.30001687", 67 | "clean-css-cli": "^5.6.3", 68 | "css-declaration-sorter": "^7.2.0", 69 | "nodemon": "^3.1.7", 70 | "npm-run-all": "^4.1.5", 71 | "postcss": "^8.4.49", 72 | "postcss-cli": "^11.0.0", 73 | "postcss-scss": "^4.0.9", 74 | "prettier": "^3.4.2", 75 | "sass": "^1.83.4" 76 | }, 77 | "engines": { 78 | "node": ">=20" 79 | }, 80 | "browserslist": [ 81 | "defaults" 82 | ] 83 | } 84 | -------------------------------------------------------------------------------- /scripts/build-dev.js: -------------------------------------------------------------------------------- 1 | const sass = require("sass"); 2 | const path = require("path"); 3 | const fs = require("fs"); 4 | 5 | const themeColors = [ 6 | //? uncomment 1 theme you'd like to build for the dev environment. 7 | //"amber", 8 | //"blue", 9 | //"cyan", 10 | //"fuchsia", 11 | //"green", 12 | //"grey", 13 | //"indigo", 14 | "indigo", 15 | //"lime", 16 | //"orange", 17 | //"pink", 18 | //"pumpkin", 19 | //"purple", 20 | //"red", 21 | //"sand", 22 | //"slate", 23 | //"violet", 24 | //"yellow", 25 | //"zinc", 26 | ]; 27 | 28 | const tempScssFoldername = path.join(__dirname, "../.pico"); 29 | const cssFoldername = path.join(__dirname, "../css"); 30 | 31 | // Create a folder if it doesn't exist 32 | const createFolderIfNotExists = (foldername) => { 33 | if (!fs.existsSync(foldername)) { 34 | fs.mkdirSync(foldername); 35 | } 36 | }; 37 | 38 | // Empty a folder 39 | const emptyFolder = (foldername) => { 40 | // Delete all files in the temp folder 41 | fs.readdirSync(foldername).forEach((file) => { 42 | fs.unlinkSync(path.join(foldername, file)); 43 | }); 44 | }; 45 | 46 | // Create the temp folder if it doesn't exist 47 | createFolderIfNotExists(tempScssFoldername); 48 | 49 | // Empty the temp folder 50 | emptyFolder(tempScssFoldername); 51 | 52 | // Loop through the theme colors 53 | themeColors.forEach((themeColor, colorIndex) => { 54 | // All the versions to generate 55 | const versions = [ 56 | { 57 | name: "pico", 58 | content: `@use "../scss" with ( 59 | $theme-color: "${themeColor}" 60 | );`, 61 | }, 62 | //{ 63 | // name: "pico.classless", 64 | // content: `@use "../scss" with ( 65 | // $theme-color: "${themeColor}", 66 | // $enable-semantic-container: true, 67 | // $enable-classes: false 68 | // );`, 69 | //}, 70 | //{ 71 | // name: "pico.fluid.classless", 72 | // content: `@use "../scss" with ( 73 | // $theme-color: "${themeColor}", 74 | // $enable-semantic-container: true, 75 | // $enable-viewport: false, 76 | // $enable-classes: false 77 | // );`, 78 | //}, 79 | //{ 80 | // name: "pico.conditional", 81 | // content: `@use "../scss" with ( 82 | // $theme-color: "${themeColor}", 83 | // $parent-selector: ".pico" 84 | // );`, 85 | //}, 86 | //{ 87 | // name: "pico.classless.conditional", 88 | // content: `@use "../scss" with ( 89 | // $theme-color: "${themeColor}", 90 | // $enable-semantic-container: true, 91 | // $enable-classes: false, 92 | // $parent-selector: ".pico" 93 | // );`, 94 | //}, 95 | //{ 96 | // name: "pico.fluid.classless.conditional", 97 | // content: `@use "../scss" with ( 98 | // $theme-color: "${themeColor}", 99 | // $enable-semantic-container: true, 100 | // $enable-viewport: false, 101 | // $enable-classes: false, 102 | // $parent-selector: ".pico" 103 | // );`, 104 | //}, 105 | ]; 106 | 107 | const displayAsciiProgress = ({length, index, color}) => { 108 | const progress = Math.round((index / length) * 100); 109 | const bar = "■".repeat(progress / 10); 110 | const empty = "□".repeat(10 - progress / 10); 111 | process.stdout.write(`[@picocss/pico] ✨ ${bar}${empty} ${color}\r`); 112 | }; 113 | 114 | // Loop through the versions 115 | versions.forEach((version) => { 116 | displayAsciiProgress({ 117 | length: themeColors.length, 118 | index: colorIndex, 119 | color: themeColor.charAt(0).toUpperCase() + themeColor.slice(1), 120 | }); 121 | 122 | // Create the file 123 | fs.writeFileSync( 124 | path.join(tempScssFoldername, `${version.name}.${themeColor}.scss`), 125 | version.content, 126 | ); 127 | 128 | // Compile the file 129 | const result = sass.compile( 130 | path.join(tempScssFoldername, `${version.name}.${themeColor}.scss`), 131 | { outputStyle: "compressed" }, 132 | ); 133 | 134 | // Write the file 135 | fs.writeFileSync(path.join(cssFoldername, `${version.name}.${themeColor}.css`), result.css); 136 | 137 | // Clear the console - only if running in a TTY 138 | if (process.stdout.isTTY) { 139 | process.stdout.clearLine(); 140 | process.stdout.cursorTo(0); 141 | } 142 | }); 143 | }); 144 | 145 | // Empty the temp folder 146 | emptyFolder(tempScssFoldername); 147 | -------------------------------------------------------------------------------- /scripts/build-themes.js: -------------------------------------------------------------------------------- 1 | const sass = require("sass"); 2 | const path = require("path"); 3 | const fs = require("fs"); 4 | 5 | const themeColors = [ 6 | "amber", 7 | "azure", 8 | "blue", 9 | "cyan", 10 | "fuchsia", 11 | "green", 12 | "grey", 13 | "indigo", 14 | "jade", 15 | "lime", 16 | "orange", 17 | "pink", 18 | "pumpkin", 19 | "purple", 20 | "red", 21 | "sand", 22 | "slate", 23 | "violet", 24 | "yellow", 25 | "zinc", 26 | ]; 27 | 28 | const tempScssFoldername = path.join(__dirname, "../.pico"); 29 | const cssFoldername = path.join(__dirname, "../css"); 30 | 31 | // Create a folder if it doesn't exist 32 | const createFolderIfNotExists = (foldername) => { 33 | if (!fs.existsSync(foldername)) { 34 | fs.mkdirSync(foldername); 35 | } 36 | }; 37 | 38 | // Empty a folder 39 | const emptyFolder = (foldername) => { 40 | // Delete all files in the temp folder 41 | fs.readdirSync(foldername).forEach((file) => { 42 | fs.unlinkSync(path.join(foldername, file)); 43 | }); 44 | }; 45 | 46 | // Create the temp folder if it doesn't exist 47 | createFolderIfNotExists(tempScssFoldername); 48 | 49 | // Empty the temp folder 50 | emptyFolder(tempScssFoldername); 51 | 52 | // Loop through the theme colors 53 | themeColors.forEach((themeColor, colorIndex) => { 54 | // All the versions to generate 55 | const versions = [ 56 | { 57 | name: "pico", 58 | content: `@use "../scss" with ( 59 | $theme-color: "${themeColor}" 60 | );`, 61 | }, 62 | { 63 | name: "pico.classless", 64 | content: `@use "../scss" with ( 65 | $theme-color: "${themeColor}", 66 | $enable-semantic-container: true, 67 | $enable-classes: false 68 | );`, 69 | }, 70 | { 71 | name: "pico.fluid.classless", 72 | content: `@use "../scss" with ( 73 | $theme-color: "${themeColor}", 74 | $enable-semantic-container: true, 75 | $enable-viewport: false, 76 | $enable-classes: false 77 | );`, 78 | }, 79 | { 80 | name: "pico.conditional", 81 | content: `@use "../scss" with ( 82 | $theme-color: "${themeColor}", 83 | $parent-selector: ".pico" 84 | );`, 85 | }, 86 | { 87 | name: "pico.classless.conditional", 88 | content: `@use "../scss" with ( 89 | $theme-color: "${themeColor}", 90 | $enable-semantic-container: true, 91 | $enable-classes: false, 92 | $parent-selector: ".pico" 93 | );`, 94 | }, 95 | { 96 | name: "pico.fluid.classless.conditional", 97 | content: `@use "../scss" with ( 98 | $theme-color: "${themeColor}", 99 | $enable-semantic-container: true, 100 | $enable-viewport: false, 101 | $enable-classes: false, 102 | $parent-selector: ".pico" 103 | );`, 104 | }, 105 | ]; 106 | 107 | const displayAsciiProgress = ({length, index, color}) => { 108 | const progress = Math.round((index / length) * 100); 109 | const bar = "■".repeat(progress / 10); 110 | const empty = "□".repeat(10 - progress / 10); 111 | process.stdout.write(`[@Yohn/PicoCSS] ✨ ${bar}${empty} ${color}\r`); 112 | }; 113 | 114 | // Loop through the versions 115 | versions.forEach((version) => { 116 | displayAsciiProgress({ 117 | length: themeColors.length, 118 | index: colorIndex, 119 | color: themeColor.charAt(0).toUpperCase() + themeColor.slice(1), 120 | }); 121 | 122 | // Create the file 123 | fs.writeFileSync( 124 | path.join(tempScssFoldername, `${version.name}.${themeColor}.scss`), 125 | version.content, 126 | ); 127 | 128 | // Compile the file 129 | const result = sass.compile( 130 | path.join(tempScssFoldername, `${version.name}.${themeColor}.scss`), 131 | { outputStyle: "compressed" }, 132 | ); 133 | 134 | // Write the file 135 | fs.writeFileSync(path.join(cssFoldername, `${version.name}.${themeColor}.css`), result.css); 136 | 137 | // Clear the console - only if running in a TTY 138 | if (process.stdout.isTTY) { 139 | process.stdout.clearLine(); 140 | process.stdout.cursorTo(0); 141 | } 142 | }); 143 | }); 144 | 145 | // Empty the temp folder 146 | emptyFolder(tempScssFoldername); 147 | -------------------------------------------------------------------------------- /scripts/copy-docs-css-files-dev.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | 4 | // Define the source and destination paths 5 | const filesToCopy = [ 6 | { src: 'css/pico.indigo.css', dest: 'docs/pico.css' }, 7 | { src: 'css/pico.indigo.min.css', dest: 'docs/pico.min.css' }, 8 | { src: 'css/pico.colors.min.css', dest: 'docs/pico.colors.min.css' } 9 | ]; 10 | 11 | // Copy each file to the destination 12 | filesToCopy.forEach(file => { 13 | fs.copyFileSync(file.src, file.dest); 14 | console.log(`[@Yohns/PicoCSS] ✨ Copied new file to ${file.dest}`); 15 | }); 16 | -------------------------------------------------------------------------------- /scripts/copy-docs-css-files.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | 4 | // Define the source and destination paths 5 | const filesToCopy = [ 6 | { src: 'css/pico.css', dest: 'docs/pico.css' }, 7 | { src: 'css/pico.min.css', dest: 'docs/pico.min.css' }, 8 | { src: 'css/pico.colors.min.css', dest: 'docs/pico.colors.min.css' } 9 | ]; 10 | 11 | // Copy each file to the destination 12 | filesToCopy.forEach(file => { 13 | fs.copyFileSync(file.src, file.dest); 14 | console.log(`[@Yohns/PicoCSS] ✨ Copied new file to ${file.dest}`); 15 | }); 16 | -------------------------------------------------------------------------------- /scss/_index.scss: -------------------------------------------------------------------------------- 1 | @use "helpers/copyright"; 2 | 3 | // Config 4 | @forward "settings"; 5 | 6 | // Theming 7 | @use "themes/default"; 8 | 9 | // Layout 10 | @use "layout/document"; // html 11 | @use "layout/landmarks"; // body, header, main, footer 12 | @use "layout/section"; // section 13 | @use "layout/container"; // .container, .container-fluid 14 | @use "layout/grid"; // .grid 15 | @use "layout/row"; // .row, .row-fluid, .offset-*, .span-* 16 | @use "layout/overflow-auto"; // .overflow-auto 17 | 18 | // Content 19 | @use "content/typography"; // headings, p, ul, blockquote, ... 20 | @use "content/link"; // a, role="link" 21 | @use "content/button"; // button, role="button", type="button", type="submit" ... 22 | @use "content/table"; // table, tr, td, ... 23 | @use "content/embedded"; // audio, canvas, iframe, img, svg, video 24 | @use "content/code"; // pre, code, ... 25 | @use "content/figure"; // figure, figcaption 26 | @use "content/misc"; // hr, template, [hidden], dialog, canvas 27 | 28 | // Forms 29 | @use "forms/basics"; // input, select, textarea, label, fieldset, legend 30 | @use "forms/checkbox-radio-switch"; // type="checkbox", type="radio", role="switch" 31 | @use "forms/input-color"; // type="color" 32 | @use "forms/input-date"; // type="date", type="datetime-local", type="month", type="time", type="week" 33 | @use "forms/input-file"; // type="file" 34 | @use "forms/input-range"; // type="range" 35 | @use "forms/input-search"; // type="search" 36 | @use "forms/validation"; // validation for all form elements except select[multiple],select[size], input:not([type="button"], [type="reset"], [type="image"], [type="submit"], [type="checkbox"], [type="radio"] 37 | @use "forms/floating"; // floating labels 38 | 39 | // Components 40 | @use "components/accordion"; // details, summary 41 | @use "components/card"; // article, role="article" 42 | @use "components/dropdown"; // details.dropdown 43 | @use "components/group"; // role="group" 44 | @use "components/loading"; // aria-busy=true 45 | @use "components/modal"; // dialog 46 | @use "components/nav"; // nav 47 | @use "components/nav-hamburger"; // role="navigation" for hamburger-menu for the nav component 48 | @use "components/progress"; // progress 49 | @use "components/tooltip"; // data-tooltip 50 | @use "components/tab"; // [role="tablist"] // classless tabs 51 | @use "components/tab-region"; // section[role="region"] // tabs 52 | @use "components/popover"; // dialog[role="alert"] 53 | // V3 Remove notification in favor of popovers.. 54 | @use "components/notification"; // dialog[role="alert"] 55 | @use "components/timeline"; // addition, kind of out of scope but wanted to add 56 | 57 | // Utilities 58 | @use "utilities/accessibility"; // -ms-touch-action, aria-* 59 | @use "utilities/reduce-motion"; // prefers-reduced-motion 60 | -------------------------------------------------------------------------------- /scss/_settings.scss: -------------------------------------------------------------------------------- 1 | @use "sass:map"; 2 | @use "sass:math"; 3 | @use "sass:list"; 4 | 5 | // Settings 6 | // –––––––––––––––––––– 7 | 8 | // Theme colors 9 | $yo-themes: ( 10 | "amber", 11 | "azure", 12 | "blue", 13 | "cyan", 14 | "fuchsia", 15 | "green", 16 | "indigo", 17 | "jade", 18 | "lime", 19 | "orange", 20 | "pink", 21 | "pumpkin", 22 | "purple", 23 | "red", 24 | "violet", 25 | "yellow" 26 | ); 27 | $random: list.nth($yo-themes, math.random(list.length($yo-themes))); 28 | // picks a random theme to use as default 29 | $theme-color: $random !default; // amber, azure, blue, cyan, fuchsia, green, grey, indigo, jade, lime, orange, pink, pumpkin, purple, red, sand, slate, violet, yellow, zinc 30 | 31 | // Prefix for CSS variables 32 | $css-var-prefix: "--pico-" !default; // Must start with "--" 33 | 34 | // Define the root element used to target
,
,