diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 423d5124d..af8a9b3d4 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,38 +1,36 @@ --- name: Bug Report -about: Create a report to help us improve. +about: Create a bug report to help us fix a demonstrable problem with code in the library. title: '' labels: bug assignees: claviska --- -**Describe the bug** -A clear and concise description of what the bug is. +### Describe the bug +A bug is _a demonstrable problem_ caused by code in the library. Please provide a clear and concise description of what the bug is here. -**To Reproduce** +### To Reproduce Steps to reproduce the behavior: + 1. Go to '...' -2. Click on '....' -3. Scroll down to '....' +2. Click on '...' +3. Scroll down to '...' 4. See error -**Expected behavior** -A clear and concise description of what you expected to happen. +### Demo -**Screenshots** -If applicable, add screenshots to help explain your problem. +If the bug isn't obvious, please provide a link to a CodePen or Fiddle with a minimal reproduction. Bugs that have repros get attention faster than those that don't. -**Desktop (please complete the following information):** - - OS: [e.g. iOS] - - Browser [e.g. chrome, safari] - - Version [e.g. 22] +Tip: use the CodePen button on any example in the docs! -**Smartphone (please complete the following information):** - - Device: [e.g. iPhone6] - - OS: [e.g. iOS8.1] - - Browser [e.g. stock browser, safari] - - Version [e.g. 22] +### Screenshots +If applicable, add screenshots to help explain the bug. -**Additional context** -Add any other context about the problem here. +### Browser / OS + - OS: [e.g. Mac, Windows] + - Browser [e.g. Chrome, Firefox, Safari] + - Browser version [e.g. 22] + +### Additional information +Provide any additional information about the bug here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index c19268892..1f020ff74 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -7,14 +7,11 @@ assignees: claviska --- -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] +### What issue are you having? +Provide a clear and concise description of the problem you're facing. -**Describe the solution you'd like** -A clear and concise description of what you want to happen. +### Describe the solution you'd like +How would you like to see the library solve it? -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - -**Additional context** -Add any other context or screenshots about the feature request here. +### Describe alternatives you've considered +In what ways have you tried to solve this with the current version? diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml new file mode 100644 index 000000000..0259d04ed --- /dev/null +++ b/.github/workflows/node.js.yml @@ -0,0 +1,31 @@ +# This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node +# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions + +name: Node.js CI + +on: + push: + branches: [ next ] + pull_request: + branches: [ next ] + +jobs: + build: + + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [14.x, 16.x] + # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ + + steps: + - uses: actions/checkout@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node-version }} + cache: 'npm' + - run: npm ci + - run: npm run build --if-present + - run: npm test diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..7449ea906 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,17 @@ +# This workflow will create a GitHub release every time a tag is pushed +name: Create GitHub Release + +on: + push: + tags: + - "v2.*" + - "v3.*" + +jobs: + release: + runs-on: ubuntu-latest + steps: + - uses: "marvinpinto/action-automatic-releases@v1.2.1" + with: + repo_token: "${{ secrets.GITHUB_TOKEN }}" + prerelease: false diff --git a/.gitignore b/.gitignore index c4f61d9a5..09e622f0e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .DS_Store .cache docs/dist +docs/search.json dist examples node_modules diff --git a/README.md b/README.md index 95f64cd92..08eded6ba 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Twitter: [@shoelace_style](https://twitter.com/shoelace_style) ## Shoemakers 🥾 -Shoemakers, or "Shoelace developers," can use this documentation to learn how to build Shoelace from source. You will need Node >= 12.10.0 to build and run the project locally. +Shoemakers, or "Shoelace developers," can use this documentation to learn how to build Shoelace from source. You will need Node >= 14 to build and run the project locally. It is preferred, but not required, to use npm 7. **You don't need to do any of this to use Shoelace!** This page is for people who want to contribute to the project, tinker with the source, or create a custom build of Shoelace. diff --git a/custom-elements-manifest.config.js b/custom-elements-manifest.config.js index 0d4be0ff4..1d6286446 100644 --- a/custom-elements-manifest.config.js +++ b/custom-elements-manifest.config.js @@ -3,6 +3,7 @@ import commentParser from 'comment-parser'; const packageData = JSON.parse(fs.readFileSync('./package.json', 'utf8')); const { name, description, version, author, homepage, license } = packageData; +const noDash = string => string.replace(/^\s?-/, '').trim(); export default { globs: ['src/components/**/*.ts'], @@ -47,7 +48,7 @@ export default { } classDoc['animations'].push({ name: t.name, - description: t.description + description: noDash(t.description) }); break; diff --git a/docs/404.md b/docs/404.md index 3d4de0e7a..822aef5f0 100644 --- a/docs/404.md +++ b/docs/404.md @@ -1,3 +1,5 @@ # Not Found -Sorry, I couldn't find that page. +Cute monsters hiding behind a tree + +Sorry, I couldn't find that page. Have you tried pressing / to search? diff --git a/docs/_sidebar.md b/docs/_sidebar.md index fc45b2676..73aff9306 100644 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -2,8 +2,8 @@ - [Overview](/) - [Installation](/getting-started/installation) - [Usage](/getting-started/usage) - - [Customizing](/getting-started/customizing) - [Themes](/getting-started/themes) + - [Customizing](/getting-started/customizing) - Resources - [Community](/resources/community) @@ -14,6 +14,8 @@ - [Alert](/components/alert) - [Avatar](/components/avatar) - [Badge](/components/badge) + - [Breadcrumb](/components/breadcrumb) + - [Breadcrumb Item](/components/breadcrumb-item) - [Button](/components/button) - [Button Group](/components/button-group) - [Card](/components/card) @@ -21,6 +23,7 @@ - [Color Picker](/components/color-picker) - [Details](/components/details) - [Dialog](/components/dialog) + - [Divider](/components/divider) - [Drawer](/components/drawer) - [Dropdown](/components/dropdown) - [Form](/components/form) @@ -29,11 +32,11 @@ - [Image Comparer](/components/image-comparer) - [Input](/components/input) - [Menu](/components/menu) - - [Menu Divider](/components/menu-divider) - [Menu Item](/components/menu-item) - [Menu Label](/components/menu-label) - [Progress Bar](/components/progress-bar) - [Progress Ring](/components/progress-ring) + - [QR Code](/components/qr-code) - [Radio](/components/radio) - [Radio Group](/components/radio-group) - [Range](/components/range) @@ -56,7 +59,7 @@ - [Format Date](/components/format-date) - [Format Number](/components/format-number) - [Include](/components/include) - - [QR Code](/components/qr-code) + - [Mutation Observer](/components/mutation-observer) - [Relative Time](/components/relative-time) - [Resize Observer](/components/resize-observer) - [Responsive Media](/components/responsive-media) diff --git a/docs/assets/images/logo.svg b/docs/assets/images/logo.svg index 287cd79a8..6d15ad28a 100644 --- a/docs/assets/images/logo.svg +++ b/docs/assets/images/logo.svg @@ -1,6 +1,6 @@ - + diff --git a/docs/assets/images/og-image.png b/docs/assets/images/og-image.png index b0c96a66e..5c35e25c2 100644 Binary files a/docs/assets/images/og-image.png and b/docs/assets/images/og-image.png differ diff --git a/docs/assets/images/touch-icon.png b/docs/assets/images/touch-icon.png index 190701270..56c2add9c 100644 Binary files a/docs/assets/images/touch-icon.png and b/docs/assets/images/touch-icon.png differ diff --git a/docs/assets/images/twitter-card.png b/docs/assets/images/twitter-card.png index 7a93088c2..964897ff9 100644 Binary files a/docs/assets/images/twitter-card.png and b/docs/assets/images/twitter-card.png differ diff --git a/docs/assets/images/undraw-content-team.svg b/docs/assets/images/undraw-content-team.svg index 3ea01ce11..df89a4450 100644 --- a/docs/assets/images/undraw-content-team.svg +++ b/docs/assets/images/undraw-content-team.svg @@ -5,7 +5,7 @@ Created with Sketch. - + @@ -22,7 +22,7 @@ - + @@ -32,7 +32,7 @@ - + @@ -50,10 +50,10 @@ - + - + @@ -67,7 +67,7 @@ - + @@ -77,4 +77,4 @@ - \ No newline at end of file + diff --git a/docs/assets/images/undraw-not-found.svg b/docs/assets/images/undraw-not-found.svg new file mode 100644 index 000000000..aea1d5053 --- /dev/null +++ b/docs/assets/images/undraw-not-found.svg @@ -0,0 +1 @@ +not found \ No newline at end of file diff --git a/docs/assets/images/wordmark.svg b/docs/assets/images/wordmark.svg index b03918ae9..f853ed3ea 100644 --- a/docs/assets/images/wordmark.svg +++ b/docs/assets/images/wordmark.svg @@ -1,6 +1,6 @@ - + diff --git a/docs/assets/plugins/code-block/code-block.css b/docs/assets/plugins/code-block/code-block.css index 864a09ec1..25a7f2a22 100644 --- a/docs/assets/plugins/code-block/code-block.css +++ b/docs/assets/plugins/code-block/code-block.css @@ -1,17 +1,17 @@ .code-block { position: relative; border-radius: 3px; - background: var(--sl-color-gray-50); + background-color: rgb(var(--sl-color-neutral-50)); margin-bottom: 1.5rem; } .code-block__preview { position: relative; - border: solid 1px var(--sl-color-gray-200); + border: solid 1px rgb(var(--sl-color-neutral-200)); border-bottom: none; border-top-left-radius: 3px; border-top-right-radius: 3px; - background-color: white; + background-color: rgb(var(--sl-color-neutral-0)); min-width: 20rem; max-width: 100%; padding: 1.5rem 3.25rem 1.5rem 1.5rem; @@ -39,22 +39,14 @@ bottom: 0; width: 1.75rem; font-size: 20px; - color: var(--sl-color-gray-500); - background-color: white; - border-left: solid 1px var(--sl-color-gray-200); + color: rgb(var(--sl-color-neutral-600)); + background-color: rgb(var(--sl-color-neutral-0)); + border-left: solid 1px rgb(var(--sl-color-neutral-200)); border-top-right-radius: 3px; cursor: ew-resize; transition: 250ms background-color; } -.code-block__resizer:focus { - outline: none; - box-shadow: 0 0 0 1px var(--sl-color-primary-400), 0 0 0 var(--sl-focus-ring-width) var(--sl-focus-ring-color-primary); - background-color: var(--sl-color-primary-50); - color: var(--sl-color-primary-500); - z-index: 2; -} - @media screen and (max-width: 600px) { .code-block__preview { padding-right: 1.5rem; @@ -66,102 +58,146 @@ } .code-block__source { - border: solid 1px var(--sl-color-gray-200); + border: solid 1px rgb(var(--sl-color-neutral-200)); border-bottom: none; border-radius: 0 !important; margin: 0; display: none; } -.code-block__source .docsify-copy-code-button { - border-top-right-radius: 0; -} - .code-block--expanded .code-block__source { display: block; } +.code-block__buttons { + position: relative; + border: solid 1px rgb(var(--sl-color-neutral-200)); + border-bottom-left-radius: 3px; + border-bottom-right-radius: 3px; + display: flex; +} + +.code-block__button { + flex: 0 0 auto; + height: 2.5rem; + min-width: 2.5rem; + border: none; + border-radius: 0; + background: rgb(var(--sl-color-neutral-0)); + font: inherit; + font-size: 0.7rem; + font-weight: 500; + text-transform: uppercase; + color: rgb(var(--sl-color-neutral-600)); + padding: 0 1rem; + cursor: pointer; +} + +.code-block__button:not(:last-of-type) { + border-right: solid 1px rgb(var(--sl-color-neutral-200)); +} + +.code-block__button--codepen { + display: flex; + place-items: center; + width: 6rem; +} + +.code-block__button:first-of-type { + border-bottom-left-radius: 3px; +} + +.code-block__button:last-of-type { + border-bottom-right-radius: 3px; +} + +.code-block__button:hover, +.code-block__button:active { + box-shadow: 0 0 0 1px rgb(var(--sl-color-primary-400)); + border-right-color: transparent; + background-color: rgb(var(--sl-color-primary-50)); + color: rgb(var(--sl-color-primary-700)); + z-index: 1; +} + +.code-block__button:focus-visible { + outline: none; + color: rgb(var(--sl-color-primary-600)); + border-color: rgb(var(--sl-color-primary-400)); + border-right-color: transparent; + background-color: rgb(var(--sl-color-primary-50)); + box-shadow: 0 0 0 1px rgb(var(--sl-color-primary-400)), var(--sl-focus-ring); + z-index: 2; +} + .code-block__toggle { position: relative; - z-index: 1; display: flex; + flex: 1 1 auto; align-items: center; justify-content: center; width: 100%; - height: 2.5rem; - border: solid 1px var(--sl-color-gray-200); - border-bottom-left-radius: 3px; - border-bottom-right-radius: 3px; - background: var(--sl-color-white); - font: inherit; - font-size: 0.875rem; - color: var(--sl-color-gray-600); + color: rgb(var(--sl-color-neutral-600)); cursor: pointer; - transition: 250ms background-color; -webkit-appearance: none; } -.code-block__toggle:hover, -.code-block__toggle:active { - border-color: var(--sl-color-primary-400); - background-color: var(--sl-color-primary-50); - color: var(--sl-color-primary-500); -} - -.code-block__toggle:focus { - outline: none; - border-color: var(--sl-color-primary-400); - background-color: var(--sl-color-primary-50); - color: var(--sl-color-primary-500); - box-shadow: 0 0 0 var(--sl-focus-ring-width) var(--sl-focus-ring-color-primary); -} - .code-block__toggle svg { width: 1em; height: 1em; margin-left: 0.25rem; - transition: 250ms transform; } .code-block--expanded .code-block__toggle svg { transform: rotate(180deg); } -/* Dark theme */ -.sl-theme-dark .code-block { - background-color: var(--sl-color-gray-800); +/* Copy button styles */ +.markdown-section .docsify-copy-code-button { + top: 4px; + right: 4px; + background-color: rgb(var(--sl-color-neutral-600)); + border-radius: var(--sl-border-radius-medium); + font-family: var(--sl-font-sans); + font-size: var(--sl-font-size-x-small); + font-weight: var(--sl-font-weight-semibold); + text-transform: uppercase; + padding: 8px; + user-select: none; + transition: 0.1s all; } -.sl-theme-dark .code-block__preview { - background-color: var(--sl-color-gray-900); - border-color: var(--sl-color-gray-800); +.markdown-section .docsify-copy-code-button.copied { + animation: pulse 0.75s; + --pulse-color: rgb(var(--sl-color-neutral-600)); } -.sl-theme-dark .code-block__source { - border-color: var(--sl-color-gray-800); +@keyframes pulse { + 0% { + box-shadow: 0 0 0 0 var(--pulse-color); + } + 70% { + box-shadow: 0 0 0 0.5rem transparent; + } + 100% { + box-shadow: 0 0 0 0 transparent; + } } -.sl-theme-dark .code-block__resizer { - border-left-color: var(--sl-color-gray-800); - background-color: var(--sl-color-gray-900); - color: var(--sl-color-gray-400); +.markdown-section .docsify-copy-code-button .label { + transition: none; } -.sl-theme-dark .code-block__toggle { - background-color: var(--sl-color-gray-900); - border-color: var(--sl-color-gray-800); - color: var(--sl-color-gray-400); +.markdown-section .docsify-copy-code-button .success, +.markdown-section .docsify-copy-code-button .error { + display: none; } -.sl-theme-dark .code-block__toggle:hover, -.sl-theme-dark .code-block__toggle:active { - background-color: var(--sl-color-gray-900); - border-color: var(--sl-color-gray-800); - color: var(--sl-color-gray-400); +.markdown-section .docsify-copy-code-button:focus-visible { + box-shadow: 0 0 0 3px rgb(var(--sl-color-neutral-500) / 50%); } -.sl-theme-dark .code-block__toggle:focus { - border-color: var(--sl-color-primary-500); - background-color: var(--sl-color-primary-900); - color: var(--sl-color-primary-500); +.markdown-section .docsify-copy-code-button:active { + background-color: rgb(var(--sl-color-neutral-600)); + transform: scale(0.92); } diff --git a/docs/assets/plugins/code-block/code-block.js b/docs/assets/plugins/code-block/code-block.js index c5f0b2d72..2f757742e 100644 --- a/docs/assets/plugins/code-block/code-block.js +++ b/docs/assets/plugins/code-block/code-block.js @@ -28,6 +28,22 @@ hook.afterEach(function (html, next) { const domParser = new DOMParser(); const doc = domParser.parseFromString(html, 'text/html'); + const codePenButton = ` + + `; [...doc.querySelectorAll('code[class^="lang-"]')].map(code => { if (code.classList.contains('preview')) { @@ -44,26 +60,30 @@
${code.textContent} -
+
${pre.outerHTML} - +
+ + + ${!code.classList.contains('no-codepen') ? codePenButton : ''} +
`; @@ -93,7 +113,6 @@ startWidth = parseInt(document.defaultView.getComputedStyle(preview).width, 10); preview.classList.add('code-block__preview--dragging'); event.preventDefault(); - resizer.focus(); document.documentElement.addEventListener('mousemove', dragMove, false); document.documentElement.addEventListener('touchmove', dragMove, false); document.documentElement.addEventListener('mouseup', dragStop, false); @@ -112,30 +131,59 @@ document.documentElement.removeEventListener('touchend', dragStop, false); }; - const handleKeyDown = event => { - if (['ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(event.key)) { - const currentWidth = preview.clientWidth; - const maxWidth = preview.parentElement.clientWidth; - const incr = event.shiftKey ? 100 : 10; - - event.preventDefault(); - - if (event.key === 'ArrowLeft') setWidth(currentWidth - incr); - if (event.key === 'ArrowRight') setWidth(currentWidth + incr); - if (event.key === 'Home') setWidth(0); - if (event.key === 'End') setWidth(maxWidth); - } - }; - const setWidth = width => (preview.style.width = width + 'px'); resizer.addEventListener('mousedown', dragStart); resizer.addEventListener('touchstart', dragStart); - resizer.addEventListener('keydown', handleKeyDown); }, false); }); }); + // Open in CodePen + document.addEventListener('click', event => { + const button = event.target.closest('button'); + + if (button?.classList.contains('code-block__button--codepen')) { + const codeBlock = button.closest('.code-block'); + const html = codeBlock.querySelector('.code-block__source > code').textContent; + const version = sessionStorage.getItem('sl-version'); + + const form = document.createElement('form'); + form.action = 'https://codepen.io/pen/define'; + form.method = 'POST'; + form.target = '_blank'; + + // Docs: https://blog.codepen.io/documentation/prefill/ + const data = { + title: '', + description: '', + tags: ['shoelace', 'web components'], + editors: '100', + head: ``, + css_external: ``, + js_external: ``, + js_module: true, + html: + `\n` + + `\n` + + `\n` + + html, + css: `body {\n font: 16px sans-serif;\n}`, + js: `` + }; + + const input = document.createElement('input'); + input.type = 'hidden'; + input.name = 'data'; + input.value = JSON.stringify(data); + form.append(input); + + document.body.append(form); + form.submit(); + form.remove(); + } + }); + // Expand and collapse code blocks document.addEventListener('click', event => { const toggle = event.target.closest('.code-block__toggle'); @@ -145,4 +193,16 @@ event.target.setAttribute('aria-expanded', codeBlock.classList.contains('code-block--expanded')); } }); + + // Show pulse when copying + document.addEventListener('click', event => { + const button = event.target.closest('.docsify-copy-code-button'); + if (button) { + button.classList.remove('copied'); + requestAnimationFrame(() => { + button.addEventListener('animationend', () => button.classList.remove('copied'), { once: true }); + button.classList.add('copied'); + }); + } + }); })(); diff --git a/docs/assets/plugins/metadata/metadata.js b/docs/assets/plugins/metadata/metadata.js index b03cc44d0..55de06b33 100644 --- a/docs/assets/plugins/metadata/metadata.js +++ b/docs/assets/plugins/metadata/metadata.js @@ -23,7 +23,9 @@ .map(prop => { return ` - ${escapeHtml(prop.name)} + + ${escapeHtml(prop.name)} + ${prop.attribute ? `${escapeHtml(prop.attribute)}` : '-'} ${escapeHtml(prop.description)} ${ @@ -32,7 +34,7 @@ ${prop.type?.text ? `${escapeHtml(prop.type?.text || '')}` : '-'} ${prop.default ? `${escapeHtml(prop.default)}` : '-'} - `; + `; }) .join('')} @@ -55,12 +57,12 @@ ${events .map( event => ` - - ${escapeHtml(event.name)} - ${escapeHtml(event.description)} - ${event.type?.text ? `${escapeHtml(event.type?.text)}` : '-'} - - ` + + ${escapeHtml(event.name)} + ${escapeHtml(event.description)} + ${event.type?.text ? `${escapeHtml(event.type?.text)}` : '-'} + + ` ) .join('')} @@ -146,11 +148,11 @@ ${styles .map( style => ` - - ${escapeHtml(style.name)} - ${escapeHtml(style.description)} - - ` + + ${escapeHtml(style.name)} + ${escapeHtml(style.description)} + + ` ) .join('')} @@ -172,11 +174,11 @@ ${parts .map( part => ` - - ${escapeHtml(part.name)} - ${escapeHtml(part.description)} - - ` + + ${escapeHtml(part.name)} + ${escapeHtml(part.description)} + + ` ) .join('')} @@ -198,11 +200,11 @@ ${animations .map( animation => ` - - ${escapeHtml(animation.name)} - ${escapeHtml(animation.description)} - - ` + + ${escapeHtml(animation.name)} + ${escapeHtml(animation.description)} + + ` ) .join('')} @@ -255,6 +257,9 @@ metadata.modules?.map(module => { module.declarations?.map(declaration => { if (declaration.customElement) { + // Generate the dist path based on the src path and attach it to the component + declaration.path = module.path.replace(/^src\//, 'dist/').replace(/\.ts$/, '.js'); + allComponents.push(declaration); } }); @@ -282,20 +287,23 @@ version.textContent = isDev ? 'Development' : isNext ? 'Next' : metadata.package.version; target.appendChild(version); + // Store version for reuse + sessionStorage.setItem('sl-version', metadata.package.version); + // Add repo buttons const buttons = document.createElement('div'); buttons.classList.add('sidebar-buttons'); buttons.innerHTML = ` - - Sponsor - - - Star - - - `; + + Sponsor + + + Star + + + `; target.appendChild(buttons); }); @@ -315,10 +323,10 @@ return next(content); } - let badgeType = 'info'; + let badgeType = 'neutral'; if (component.status === 'stable') badgeType = 'primary'; if (component.status === 'experimental') badgeType = 'warning'; - if (component.status === 'planned') badgeType = 'info'; + if (component.status === 'planned') badgeType = 'neutral'; if (component.status === 'deprecated') badgeType = 'danger'; result += ` @@ -328,7 +336,7 @@
- + Since ${component.since || '?'} @@ -426,11 +434,60 @@ `; } + if (component.path) { + /* prettier-ignore */ + result += ` + ## Importing + + + CDN + Bundler + React + + \n + To import this component from [the CDN](https://www.jsdelivr.com/package/npm/@shoelace-style/shoelace): + + \`\`\`js + import 'https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@${metadata.package.version}/${component.path}'; + \`\`\` + + + \n + To import this component using [a bundler](/getting-started/installation#bundling): + \`\`\`js + import '@shoelace-style/shoelace/${component.path}'; + \`\`\` + + + \n + To import this component using [\`@shoelace-style/react\`](https://www.npmjs.com/package/@shoelace-style/react): + \`\`\`js + import '@shoelace-style/react/dist/${component.tagName.replace(/^sl-/, '')}'; + \`\`\` + + + `; + } + // Strip whitespace so markdown doesn't process things as code blocks return result.replace(/^ +| +$/gm, ''); }); next(content); }); + + // Wrap tables so we can scroll them horizontally when needed + hook.doneEach(function () { + const content = document.querySelector('.content'); + const tables = [...content.querySelectorAll('table')]; + + tables.map(table => { + table.outerHTML = ` +
+ ${table.outerHTML} +
+ `; + }); + }); }); })(); diff --git a/docs/assets/plugins/search/lunr.min.js b/docs/assets/plugins/search/lunr.min.js new file mode 100644 index 000000000..d746af24a --- /dev/null +++ b/docs/assets/plugins/search/lunr.min.js @@ -0,0 +1,1310 @@ +/** + * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 2.3.9 + * Copyright (C) 2020 Oliver Nightingale + * @license MIT + */ +!(function () { + var e = function (t) { + var r = new e.Builder(); + return ( + r.pipeline.add(e.trimmer, e.stopWordFilter, e.stemmer), r.searchPipeline.add(e.stemmer), t.call(r, r), r.build() + ); + }; + (e.version = '2.3.9'), + (e.utils = {}), + (e.utils.warn = (function (e) { + return function (t) { + e.console && console.warn && console.warn(t); + }; + })(this)), + (e.utils.asString = function (e) { + return void 0 === e || null === e ? '' : e.toString(); + }), + (e.utils.clone = function (e) { + if (null === e || void 0 === e) return e; + for (var t = Object.create(null), r = Object.keys(e), i = 0; i < r.length; i++) { + var n = r[i], + s = e[n]; + if (Array.isArray(s)) t[n] = s.slice(); + else { + if ('string' != typeof s && 'number' != typeof s && 'boolean' != typeof s) + throw new TypeError('clone is not deep and does not support nested objects'); + t[n] = s; + } + } + return t; + }), + (e.FieldRef = function (e, t, r) { + (this.docRef = e), (this.fieldName = t), (this._stringValue = r); + }), + (e.FieldRef.joiner = '/'), + (e.FieldRef.fromString = function (t) { + var r = t.indexOf(e.FieldRef.joiner); + if (r === -1) throw 'malformed field ref string'; + var i = t.slice(0, r), + n = t.slice(r + 1); + return new e.FieldRef(n, i, t); + }), + (e.FieldRef.prototype.toString = function () { + return ( + void 0 == this._stringValue && (this._stringValue = this.fieldName + e.FieldRef.joiner + this.docRef), + this._stringValue + ); + }), + (e.Set = function (e) { + if (((this.elements = Object.create(null)), e)) { + this.length = e.length; + for (var t = 0; t < this.length; t++) this.elements[e[t]] = !0; + } else this.length = 0; + }), + (e.Set.complete = { + intersect: function (e) { + return e; + }, + union: function () { + return this; + }, + contains: function () { + return !0; + } + }), + (e.Set.empty = { + intersect: function () { + return this; + }, + union: function (e) { + return e; + }, + contains: function () { + return !1; + } + }), + (e.Set.prototype.contains = function (e) { + return !!this.elements[e]; + }), + (e.Set.prototype.intersect = function (t) { + var r, + i, + n, + s = []; + if (t === e.Set.complete) return this; + if (t === e.Set.empty) return t; + this.length < t.length ? ((r = this), (i = t)) : ((r = t), (i = this)), (n = Object.keys(r.elements)); + for (var o = 0; o < n.length; o++) { + var a = n[o]; + a in i.elements && s.push(a); + } + return new e.Set(s); + }), + (e.Set.prototype.union = function (t) { + return t === e.Set.complete + ? e.Set.complete + : t === e.Set.empty + ? this + : new e.Set(Object.keys(this.elements).concat(Object.keys(t.elements))); + }), + (e.idf = function (e, t) { + var r = 0; + for (var i in e) '_index' != i && (r += Object.keys(e[i]).length); + var n = (t - r + 0.5) / (r + 0.5); + return Math.log(1 + Math.abs(n)); + }), + (e.Token = function (e, t) { + (this.str = e || ''), (this.metadata = t || {}); + }), + (e.Token.prototype.toString = function () { + return this.str; + }), + (e.Token.prototype.update = function (e) { + return (this.str = e(this.str, this.metadata)), this; + }), + (e.Token.prototype.clone = function (t) { + return ( + (t = + t || + function (e) { + return e; + }), + new e.Token(t(this.str, this.metadata), this.metadata) + ); + }), + (e.tokenizer = function (t, r) { + if (null == t || void 0 == t) return []; + if (Array.isArray(t)) + return t.map(function (t) { + return new e.Token(e.utils.asString(t).toLowerCase(), e.utils.clone(r)); + }); + for (var i = t.toString().toLowerCase(), n = i.length, s = [], o = 0, a = 0; o <= n; o++) { + var u = i.charAt(o), + l = o - a; + if (u.match(e.tokenizer.separator) || o == n) { + if (l > 0) { + var c = e.utils.clone(r) || {}; + (c.position = [a, l]), (c.index = s.length), s.push(new e.Token(i.slice(a, o), c)); + } + a = o + 1; + } + } + return s; + }), + (e.tokenizer.separator = /[\s\-]+/), + (e.Pipeline = function () { + this._stack = []; + }), + (e.Pipeline.registeredFunctions = Object.create(null)), + (e.Pipeline.registerFunction = function (t, r) { + r in this.registeredFunctions && e.utils.warn('Overwriting existing registered function: ' + r), + (t.label = r), + (e.Pipeline.registeredFunctions[t.label] = t); + }), + (e.Pipeline.warnIfFunctionNotRegistered = function (t) { + var r = t.label && t.label in this.registeredFunctions; + r || + e.utils.warn( + 'Function is not registered with pipeline. This may cause problems when serialising the index.\n', + t + ); + }), + (e.Pipeline.load = function (t) { + var r = new e.Pipeline(); + return ( + t.forEach(function (t) { + var i = e.Pipeline.registeredFunctions[t]; + if (!i) throw new Error('Cannot load unregistered function: ' + t); + r.add(i); + }), + r + ); + }), + (e.Pipeline.prototype.add = function () { + var t = Array.prototype.slice.call(arguments); + t.forEach(function (t) { + e.Pipeline.warnIfFunctionNotRegistered(t), this._stack.push(t); + }, this); + }), + (e.Pipeline.prototype.after = function (t, r) { + e.Pipeline.warnIfFunctionNotRegistered(r); + var i = this._stack.indexOf(t); + if (i == -1) throw new Error('Cannot find existingFn'); + (i += 1), this._stack.splice(i, 0, r); + }), + (e.Pipeline.prototype.before = function (t, r) { + e.Pipeline.warnIfFunctionNotRegistered(r); + var i = this._stack.indexOf(t); + if (i == -1) throw new Error('Cannot find existingFn'); + this._stack.splice(i, 0, r); + }), + (e.Pipeline.prototype.remove = function (e) { + var t = this._stack.indexOf(e); + t != -1 && this._stack.splice(t, 1); + }), + (e.Pipeline.prototype.run = function (e) { + for (var t = this._stack.length, r = 0; r < t; r++) { + for (var i = this._stack[r], n = [], s = 0; s < e.length; s++) { + var o = i(e[s], s, e); + if (null !== o && void 0 !== o && '' !== o) + if (Array.isArray(o)) for (var a = 0; a < o.length; a++) n.push(o[a]); + else n.push(o); + } + e = n; + } + return e; + }), + (e.Pipeline.prototype.runString = function (t, r) { + var i = new e.Token(t, r); + return this.run([i]).map(function (e) { + return e.toString(); + }); + }), + (e.Pipeline.prototype.reset = function () { + this._stack = []; + }), + (e.Pipeline.prototype.toJSON = function () { + return this._stack.map(function (t) { + return e.Pipeline.warnIfFunctionNotRegistered(t), t.label; + }); + }), + (e.Vector = function (e) { + (this._magnitude = 0), (this.elements = e || []); + }), + (e.Vector.prototype.positionForIndex = function (e) { + if (0 == this.elements.length) return 0; + for ( + var t = 0, r = this.elements.length / 2, i = r - t, n = Math.floor(i / 2), s = this.elements[2 * n]; + i > 1 && (s < e && (t = n), s > e && (r = n), s != e); + + ) + (i = r - t), (n = t + Math.floor(i / 2)), (s = this.elements[2 * n]); + return s == e ? 2 * n : s > e ? 2 * n : s < e ? 2 * (n + 1) : void 0; + }), + (e.Vector.prototype.insert = function (e, t) { + this.upsert(e, t, function () { + throw 'duplicate index'; + }); + }), + (e.Vector.prototype.upsert = function (e, t, r) { + this._magnitude = 0; + var i = this.positionForIndex(e); + this.elements[i] == e ? (this.elements[i + 1] = r(this.elements[i + 1], t)) : this.elements.splice(i, 0, e, t); + }), + (e.Vector.prototype.magnitude = function () { + if (this._magnitude) return this._magnitude; + for (var e = 0, t = this.elements.length, r = 1; r < t; r += 2) { + var i = this.elements[r]; + e += i * i; + } + return (this._magnitude = Math.sqrt(e)); + }), + (e.Vector.prototype.dot = function (e) { + for ( + var t = 0, r = this.elements, i = e.elements, n = r.length, s = i.length, o = 0, a = 0, u = 0, l = 0; + u < n && l < s; + + ) + (o = r[u]), + (a = i[l]), + o < a ? (u += 2) : o > a ? (l += 2) : o == a && ((t += r[u + 1] * i[l + 1]), (u += 2), (l += 2)); + return t; + }), + (e.Vector.prototype.similarity = function (e) { + return this.dot(e) / this.magnitude() || 0; + }), + (e.Vector.prototype.toArray = function () { + for (var e = new Array(this.elements.length / 2), t = 1, r = 0; t < this.elements.length; t += 2, r++) + e[r] = this.elements[t]; + return e; + }), + (e.Vector.prototype.toJSON = function () { + return this.elements; + }), + (e.stemmer = (function () { + var e = { + ational: 'ate', + tional: 'tion', + enci: 'ence', + anci: 'ance', + izer: 'ize', + bli: 'ble', + alli: 'al', + entli: 'ent', + eli: 'e', + ousli: 'ous', + ization: 'ize', + ation: 'ate', + ator: 'ate', + alism: 'al', + iveness: 'ive', + fulness: 'ful', + ousness: 'ous', + aliti: 'al', + iviti: 'ive', + biliti: 'ble', + logi: 'log' + }, + t = { icate: 'ic', ative: '', alize: 'al', iciti: 'ic', ical: 'ic', ful: '', ness: '' }, + r = '[^aeiou]', + i = '[aeiouy]', + n = r + '[^aeiouy]*', + s = i + '[aeiou]*', + o = '^(' + n + ')?' + s + n, + a = '^(' + n + ')?' + s + n + '(' + s + ')?$', + u = '^(' + n + ')?' + s + n + s + n, + l = '^(' + n + ')?' + i, + c = new RegExp(o), + h = new RegExp(u), + d = new RegExp(a), + f = new RegExp(l), + p = /^(.+?)(ss|i)es$/, + y = /^(.+?)([^s])s$/, + m = /^(.+?)eed$/, + v = /^(.+?)(ed|ing)$/, + g = /.$/, + x = /(at|bl|iz)$/, + w = new RegExp('([^aeiouylsz])\\1$'), + Q = new RegExp('^' + n + i + '[^aeiouwxy]$'), + k = /^(.+?[^aeiou])y$/, + S = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/, + E = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/, + L = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/, + b = /^(.+?)(s|t)(ion)$/, + P = /^(.+?)e$/, + T = /ll$/, + O = new RegExp('^' + n + i + '[^aeiouwxy]$'), + I = function (r) { + var i, n, s, o, a, u, l; + if (r.length < 3) return r; + if ( + ((s = r.substr(0, 1)), + 'y' == s && (r = s.toUpperCase() + r.substr(1)), + (o = p), + (a = y), + o.test(r) ? (r = r.replace(o, '$1$2')) : a.test(r) && (r = r.replace(a, '$1$2')), + (o = m), + (a = v), + o.test(r)) + ) { + var I = o.exec(r); + (o = c), o.test(I[1]) && ((o = g), (r = r.replace(o, ''))); + } else if (a.test(r)) { + var I = a.exec(r); + (i = I[1]), + (a = f), + a.test(i) && + ((r = i), + (a = x), + (u = w), + (l = Q), + a.test(r) ? (r += 'e') : u.test(r) ? ((o = g), (r = r.replace(o, ''))) : l.test(r) && (r += 'e')); + } + if (((o = k), o.test(r))) { + var I = o.exec(r); + (i = I[1]), (r = i + 'i'); + } + if (((o = S), o.test(r))) { + var I = o.exec(r); + (i = I[1]), (n = I[2]), (o = c), o.test(i) && (r = i + e[n]); + } + if (((o = E), o.test(r))) { + var I = o.exec(r); + (i = I[1]), (n = I[2]), (o = c), o.test(i) && (r = i + t[n]); + } + if (((o = L), (a = b), o.test(r))) { + var I = o.exec(r); + (i = I[1]), (o = h), o.test(i) && (r = i); + } else if (a.test(r)) { + var I = a.exec(r); + (i = I[1] + I[2]), (a = h), a.test(i) && (r = i); + } + if (((o = P), o.test(r))) { + var I = o.exec(r); + (i = I[1]), (o = h), (a = d), (u = O), (o.test(i) || (a.test(i) && !u.test(i))) && (r = i); + } + return ( + (o = T), + (a = h), + o.test(r) && a.test(r) && ((o = g), (r = r.replace(o, ''))), + 'y' == s && (r = s.toLowerCase() + r.substr(1)), + r + ); + }; + return function (e) { + return e.update(I); + }; + })()), + e.Pipeline.registerFunction(e.stemmer, 'stemmer'), + (e.generateStopWordFilter = function (e) { + var t = e.reduce(function (e, t) { + return (e[t] = t), e; + }, {}); + return function (e) { + if (e && t[e.toString()] !== e.toString()) return e; + }; + }), + (e.stopWordFilter = e.generateStopWordFilter([ + 'a', + 'able', + 'about', + 'across', + 'after', + 'all', + 'almost', + 'also', + 'am', + 'among', + 'an', + 'and', + 'any', + 'are', + 'as', + 'at', + 'be', + 'because', + 'been', + 'but', + 'by', + 'can', + 'cannot', + 'could', + 'dear', + 'did', + 'do', + 'does', + 'either', + 'else', + 'ever', + 'every', + 'for', + 'from', + 'get', + 'got', + 'had', + 'has', + 'have', + 'he', + 'her', + 'hers', + 'him', + 'his', + 'how', + 'however', + 'i', + 'if', + 'in', + 'into', + 'is', + 'it', + 'its', + 'just', + 'least', + 'let', + 'like', + 'likely', + 'may', + 'me', + 'might', + 'most', + 'must', + 'my', + 'neither', + 'no', + 'nor', + 'not', + 'of', + 'off', + 'often', + 'on', + 'only', + 'or', + 'other', + 'our', + 'own', + 'rather', + 'said', + 'say', + 'says', + 'she', + 'should', + 'since', + 'so', + 'some', + 'than', + 'that', + 'the', + 'their', + 'them', + 'then', + 'there', + 'these', + 'they', + 'this', + 'tis', + 'to', + 'too', + 'twas', + 'us', + 'wants', + 'was', + 'we', + 'were', + 'what', + 'when', + 'where', + 'which', + 'while', + 'who', + 'whom', + 'why', + 'will', + 'with', + 'would', + 'yet', + 'you', + 'your' + ])), + e.Pipeline.registerFunction(e.stopWordFilter, 'stopWordFilter'), + (e.trimmer = function (e) { + return e.update(function (e) { + return e.replace(/^\W+/, '').replace(/\W+$/, ''); + }); + }), + e.Pipeline.registerFunction(e.trimmer, 'trimmer'), + (e.TokenSet = function () { + (this['final'] = !1), (this.edges = {}), (this.id = e.TokenSet._nextId), (e.TokenSet._nextId += 1); + }), + (e.TokenSet._nextId = 1), + (e.TokenSet.fromArray = function (t) { + for (var r = new e.TokenSet.Builder(), i = 0, n = t.length; i < n; i++) r.insert(t[i]); + return r.finish(), r.root; + }), + (e.TokenSet.fromClause = function (t) { + return 'editDistance' in t ? e.TokenSet.fromFuzzyString(t.term, t.editDistance) : e.TokenSet.fromString(t.term); + }), + (e.TokenSet.fromFuzzyString = function (t, r) { + for (var i = new e.TokenSet(), n = [{ node: i, editsRemaining: r, str: t }]; n.length; ) { + var s = n.pop(); + if (s.str.length > 0) { + var o, + a = s.str.charAt(0); + a in s.node.edges ? (o = s.node.edges[a]) : ((o = new e.TokenSet()), (s.node.edges[a] = o)), + 1 == s.str.length && (o['final'] = !0), + n.push({ node: o, editsRemaining: s.editsRemaining, str: s.str.slice(1) }); + } + if (0 != s.editsRemaining) { + if ('*' in s.node.edges) var u = s.node.edges['*']; + else { + var u = new e.TokenSet(); + s.node.edges['*'] = u; + } + if ( + (0 == s.str.length && (u['final'] = !0), + n.push({ node: u, editsRemaining: s.editsRemaining - 1, str: s.str }), + s.str.length > 1 && n.push({ node: s.node, editsRemaining: s.editsRemaining - 1, str: s.str.slice(1) }), + 1 == s.str.length && (s.node['final'] = !0), + s.str.length >= 1) + ) { + if ('*' in s.node.edges) var l = s.node.edges['*']; + else { + var l = new e.TokenSet(); + s.node.edges['*'] = l; + } + 1 == s.str.length && (l['final'] = !0), + n.push({ node: l, editsRemaining: s.editsRemaining - 1, str: s.str.slice(1) }); + } + if (s.str.length > 1) { + var c, + h = s.str.charAt(0), + d = s.str.charAt(1); + d in s.node.edges ? (c = s.node.edges[d]) : ((c = new e.TokenSet()), (s.node.edges[d] = c)), + 1 == s.str.length && (c['final'] = !0), + n.push({ node: c, editsRemaining: s.editsRemaining - 1, str: h + s.str.slice(2) }); + } + } + } + return i; + }), + (e.TokenSet.fromString = function (t) { + for (var r = new e.TokenSet(), i = r, n = 0, s = t.length; n < s; n++) { + var o = t[n], + a = n == s - 1; + if ('*' == o) (r.edges[o] = r), (r['final'] = a); + else { + var u = new e.TokenSet(); + (u['final'] = a), (r.edges[o] = u), (r = u); + } + } + return i; + }), + (e.TokenSet.prototype.toArray = function () { + for (var e = [], t = [{ prefix: '', node: this }]; t.length; ) { + var r = t.pop(), + i = Object.keys(r.node.edges), + n = i.length; + r.node['final'] && (r.prefix.charAt(0), e.push(r.prefix)); + for (var s = 0; s < n; s++) { + var o = i[s]; + t.push({ prefix: r.prefix.concat(o), node: r.node.edges[o] }); + } + } + return e; + }), + (e.TokenSet.prototype.toString = function () { + if (this._str) return this._str; + for (var e = this['final'] ? '1' : '0', t = Object.keys(this.edges).sort(), r = t.length, i = 0; i < r; i++) { + var n = t[i], + s = this.edges[n]; + e = e + n + s.id; + } + return e; + }), + (e.TokenSet.prototype.intersect = function (t) { + for (var r = new e.TokenSet(), i = void 0, n = [{ qNode: t, output: r, node: this }]; n.length; ) { + i = n.pop(); + for ( + var s = Object.keys(i.qNode.edges), o = s.length, a = Object.keys(i.node.edges), u = a.length, l = 0; + l < o; + l++ + ) + for (var c = s[l], h = 0; h < u; h++) { + var d = a[h]; + if (d == c || '*' == c) { + var f = i.node.edges[d], + p = i.qNode.edges[c], + y = f['final'] && p['final'], + m = void 0; + d in i.output.edges + ? ((m = i.output.edges[d]), (m['final'] = m['final'] || y)) + : ((m = new e.TokenSet()), (m['final'] = y), (i.output.edges[d] = m)), + n.push({ qNode: p, output: m, node: f }); + } + } + } + return r; + }), + (e.TokenSet.Builder = function () { + (this.previousWord = ''), (this.root = new e.TokenSet()), (this.uncheckedNodes = []), (this.minimizedNodes = {}); + }), + (e.TokenSet.Builder.prototype.insert = function (t) { + var r, + i = 0; + if (t < this.previousWord) throw new Error('Out of order word insertion'); + for (var n = 0; n < t.length && n < this.previousWord.length && t[n] == this.previousWord[n]; n++) i++; + this.minimize(i), + (r = 0 == this.uncheckedNodes.length ? this.root : this.uncheckedNodes[this.uncheckedNodes.length - 1].child); + for (var n = i; n < t.length; n++) { + var s = new e.TokenSet(), + o = t[n]; + (r.edges[o] = s), this.uncheckedNodes.push({ parent: r, char: o, child: s }), (r = s); + } + (r['final'] = !0), (this.previousWord = t); + }), + (e.TokenSet.Builder.prototype.finish = function () { + this.minimize(0); + }), + (e.TokenSet.Builder.prototype.minimize = function (e) { + for (var t = this.uncheckedNodes.length - 1; t >= e; t--) { + var r = this.uncheckedNodes[t], + i = r.child.toString(); + i in this.minimizedNodes + ? (r.parent.edges[r['char']] = this.minimizedNodes[i]) + : ((r.child._str = i), (this.minimizedNodes[i] = r.child)), + this.uncheckedNodes.pop(); + } + }), + (e.Index = function (e) { + (this.invertedIndex = e.invertedIndex), + (this.fieldVectors = e.fieldVectors), + (this.tokenSet = e.tokenSet), + (this.fields = e.fields), + (this.pipeline = e.pipeline); + }), + (e.Index.prototype.search = function (t) { + return this.query(function (r) { + var i = new e.QueryParser(t, r); + i.parse(); + }); + }), + (e.Index.prototype.query = function (t) { + for ( + var r = new e.Query(this.fields), + i = Object.create(null), + n = Object.create(null), + s = Object.create(null), + o = Object.create(null), + a = Object.create(null), + u = 0; + u < this.fields.length; + u++ + ) + n[this.fields[u]] = new e.Vector(); + t.call(r, r); + for (var u = 0; u < r.clauses.length; u++) { + var l = r.clauses[u], + c = null, + h = e.Set.empty; + c = l.usePipeline ? this.pipeline.runString(l.term, { fields: l.fields }) : [l.term]; + for (var d = 0; d < c.length; d++) { + var f = c[d]; + l.term = f; + var p = e.TokenSet.fromClause(l), + y = this.tokenSet.intersect(p).toArray(); + if (0 === y.length && l.presence === e.Query.presence.REQUIRED) { + for (var m = 0; m < l.fields.length; m++) { + var v = l.fields[m]; + o[v] = e.Set.empty; + } + break; + } + for (var g = 0; g < y.length; g++) + for (var x = y[g], w = this.invertedIndex[x], Q = w._index, m = 0; m < l.fields.length; m++) { + var v = l.fields[m], + k = w[v], + S = Object.keys(k), + E = x + '/' + v, + L = new e.Set(S); + if ( + (l.presence == e.Query.presence.REQUIRED && + ((h = h.union(L)), void 0 === o[v] && (o[v] = e.Set.complete)), + l.presence != e.Query.presence.PROHIBITED) + ) { + if ( + (n[v].upsert(Q, l.boost, function (e, t) { + return e + t; + }), + !s[E]) + ) { + for (var b = 0; b < S.length; b++) { + var P, + T = S[b], + O = new e.FieldRef(T, v), + I = k[T]; + void 0 === (P = i[O]) ? (i[O] = new e.MatchData(x, v, I)) : P.add(x, v, I); + } + s[E] = !0; + } + } else void 0 === a[v] && (a[v] = e.Set.empty), (a[v] = a[v].union(L)); + } + } + if (l.presence === e.Query.presence.REQUIRED) + for (var m = 0; m < l.fields.length; m++) { + var v = l.fields[m]; + o[v] = o[v].intersect(h); + } + } + for (var R = e.Set.complete, F = e.Set.empty, u = 0; u < this.fields.length; u++) { + var v = this.fields[u]; + o[v] && (R = R.intersect(o[v])), a[v] && (F = F.union(a[v])); + } + var C = Object.keys(i), + N = [], + _ = Object.create(null); + if (r.isNegated()) { + C = Object.keys(this.fieldVectors); + for (var u = 0; u < C.length; u++) { + var O = C[u], + j = e.FieldRef.fromString(O); + i[O] = new e.MatchData(); + } + } + for (var u = 0; u < C.length; u++) { + var j = e.FieldRef.fromString(C[u]), + D = j.docRef; + if (R.contains(D) && !F.contains(D)) { + var A, + B = this.fieldVectors[j], + V = n[j.fieldName].similarity(B); + if (void 0 !== (A = _[D])) (A.score += V), A.matchData.combine(i[j]); + else { + var z = { ref: D, score: V, matchData: i[j] }; + (_[D] = z), N.push(z); + } + } + } + return N.sort(function (e, t) { + return t.score - e.score; + }); + }), + (e.Index.prototype.toJSON = function () { + var t = Object.keys(this.invertedIndex) + .sort() + .map(function (e) { + return [e, this.invertedIndex[e]]; + }, this), + r = Object.keys(this.fieldVectors).map(function (e) { + return [e, this.fieldVectors[e].toJSON()]; + }, this); + return { + version: e.version, + fields: this.fields, + fieldVectors: r, + invertedIndex: t, + pipeline: this.pipeline.toJSON() + }; + }), + (e.Index.load = function (t) { + var r = {}, + i = {}, + n = t.fieldVectors, + s = Object.create(null), + o = t.invertedIndex, + a = new e.TokenSet.Builder(), + u = e.Pipeline.load(t.pipeline); + t.version != e.version && + e.utils.warn( + "Version mismatch when loading serialised index. Current version of lunr '" + + e.version + + "' does not match serialized index '" + + t.version + + "'" + ); + for (var l = 0; l < n.length; l++) { + var c = n[l], + h = c[0], + d = c[1]; + i[h] = new e.Vector(d); + } + for (var l = 0; l < o.length; l++) { + var c = o[l], + f = c[0], + p = c[1]; + a.insert(f), (s[f] = p); + } + return ( + a.finish(), + (r.fields = t.fields), + (r.fieldVectors = i), + (r.invertedIndex = s), + (r.tokenSet = a.root), + (r.pipeline = u), + new e.Index(r) + ); + }), + (e.Builder = function () { + (this._ref = 'id'), + (this._fields = Object.create(null)), + (this._documents = Object.create(null)), + (this.invertedIndex = Object.create(null)), + (this.fieldTermFrequencies = {}), + (this.fieldLengths = {}), + (this.tokenizer = e.tokenizer), + (this.pipeline = new e.Pipeline()), + (this.searchPipeline = new e.Pipeline()), + (this.documentCount = 0), + (this._b = 0.75), + (this._k1 = 1.2), + (this.termIndex = 0), + (this.metadataWhitelist = []); + }), + (e.Builder.prototype.ref = function (e) { + this._ref = e; + }), + (e.Builder.prototype.field = function (e, t) { + if (/\//.test(e)) throw new RangeError("Field '" + e + "' contains illegal character '/'"); + this._fields[e] = t || {}; + }), + (e.Builder.prototype.b = function (e) { + e < 0 ? (this._b = 0) : e > 1 ? (this._b = 1) : (this._b = e); + }), + (e.Builder.prototype.k1 = function (e) { + this._k1 = e; + }), + (e.Builder.prototype.add = function (t, r) { + var i = t[this._ref], + n = Object.keys(this._fields); + (this._documents[i] = r || {}), (this.documentCount += 1); + for (var s = 0; s < n.length; s++) { + var o = n[s], + a = this._fields[o].extractor, + u = a ? a(t) : t[o], + l = this.tokenizer(u, { fields: [o] }), + c = this.pipeline.run(l), + h = new e.FieldRef(i, o), + d = Object.create(null); + (this.fieldTermFrequencies[h] = d), (this.fieldLengths[h] = 0), (this.fieldLengths[h] += c.length); + for (var f = 0; f < c.length; f++) { + var p = c[f]; + if ((void 0 == d[p] && (d[p] = 0), (d[p] += 1), void 0 == this.invertedIndex[p])) { + var y = Object.create(null); + (y._index = this.termIndex), (this.termIndex += 1); + for (var m = 0; m < n.length; m++) y[n[m]] = Object.create(null); + this.invertedIndex[p] = y; + } + void 0 == this.invertedIndex[p][o][i] && (this.invertedIndex[p][o][i] = Object.create(null)); + for (var v = 0; v < this.metadataWhitelist.length; v++) { + var g = this.metadataWhitelist[v], + x = p.metadata[g]; + void 0 == this.invertedIndex[p][o][i][g] && (this.invertedIndex[p][o][i][g] = []), + this.invertedIndex[p][o][i][g].push(x); + } + } + } + }), + (e.Builder.prototype.calculateAverageFieldLengths = function () { + for (var t = Object.keys(this.fieldLengths), r = t.length, i = {}, n = {}, s = 0; s < r; s++) { + var o = e.FieldRef.fromString(t[s]), + a = o.fieldName; + n[a] || (n[a] = 0), (n[a] += 1), i[a] || (i[a] = 0), (i[a] += this.fieldLengths[o]); + } + for (var u = Object.keys(this._fields), s = 0; s < u.length; s++) { + var l = u[s]; + i[l] = i[l] / n[l]; + } + this.averageFieldLength = i; + }), + (e.Builder.prototype.createFieldVectors = function () { + for ( + var t = {}, r = Object.keys(this.fieldTermFrequencies), i = r.length, n = Object.create(null), s = 0; + s < i; + s++ + ) { + for ( + var o = e.FieldRef.fromString(r[s]), + a = o.fieldName, + u = this.fieldLengths[o], + l = new e.Vector(), + c = this.fieldTermFrequencies[o], + h = Object.keys(c), + d = h.length, + f = this._fields[a].boost || 1, + p = this._documents[o.docRef].boost || 1, + y = 0; + y < d; + y++ + ) { + var m, + v, + g, + x = h[y], + w = c[x], + Q = this.invertedIndex[x]._index; + void 0 === n[x] ? ((m = e.idf(this.invertedIndex[x], this.documentCount)), (n[x] = m)) : (m = n[x]), + (v = + (m * ((this._k1 + 1) * w)) / (this._k1 * (1 - this._b + this._b * (u / this.averageFieldLength[a])) + w)), + (v *= f), + (v *= p), + (g = Math.round(1e3 * v) / 1e3), + l.insert(Q, g); + } + t[o] = l; + } + this.fieldVectors = t; + }), + (e.Builder.prototype.createTokenSet = function () { + this.tokenSet = e.TokenSet.fromArray(Object.keys(this.invertedIndex).sort()); + }), + (e.Builder.prototype.build = function () { + return ( + this.calculateAverageFieldLengths(), + this.createFieldVectors(), + this.createTokenSet(), + new e.Index({ + invertedIndex: this.invertedIndex, + fieldVectors: this.fieldVectors, + tokenSet: this.tokenSet, + fields: Object.keys(this._fields), + pipeline: this.searchPipeline + }) + ); + }), + (e.Builder.prototype.use = function (e) { + var t = Array.prototype.slice.call(arguments, 1); + t.unshift(this), e.apply(this, t); + }), + (e.MatchData = function (e, t, r) { + for (var i = Object.create(null), n = Object.keys(r || {}), s = 0; s < n.length; s++) { + var o = n[s]; + i[o] = r[o].slice(); + } + (this.metadata = Object.create(null)), + void 0 !== e && ((this.metadata[e] = Object.create(null)), (this.metadata[e][t] = i)); + }), + (e.MatchData.prototype.combine = function (e) { + for (var t = Object.keys(e.metadata), r = 0; r < t.length; r++) { + var i = t[r], + n = Object.keys(e.metadata[i]); + void 0 == this.metadata[i] && (this.metadata[i] = Object.create(null)); + for (var s = 0; s < n.length; s++) { + var o = n[s], + a = Object.keys(e.metadata[i][o]); + void 0 == this.metadata[i][o] && (this.metadata[i][o] = Object.create(null)); + for (var u = 0; u < a.length; u++) { + var l = a[u]; + void 0 == this.metadata[i][o][l] + ? (this.metadata[i][o][l] = e.metadata[i][o][l]) + : (this.metadata[i][o][l] = this.metadata[i][o][l].concat(e.metadata[i][o][l])); + } + } + } + }), + (e.MatchData.prototype.add = function (e, t, r) { + if (!(e in this.metadata)) return (this.metadata[e] = Object.create(null)), void (this.metadata[e][t] = r); + if (!(t in this.metadata[e])) return void (this.metadata[e][t] = r); + for (var i = Object.keys(r), n = 0; n < i.length; n++) { + var s = i[n]; + s in this.metadata[e][t] + ? (this.metadata[e][t][s] = this.metadata[e][t][s].concat(r[s])) + : (this.metadata[e][t][s] = r[s]); + } + }), + (e.Query = function (e) { + (this.clauses = []), (this.allFields = e); + }), + (e.Query.wildcard = new String('*')), + (e.Query.wildcard.NONE = 0), + (e.Query.wildcard.LEADING = 1), + (e.Query.wildcard.TRAILING = 2), + (e.Query.presence = { OPTIONAL: 1, REQUIRED: 2, PROHIBITED: 3 }), + (e.Query.prototype.clause = function (t) { + return ( + 'fields' in t || (t.fields = this.allFields), + 'boost' in t || (t.boost = 1), + 'usePipeline' in t || (t.usePipeline = !0), + 'wildcard' in t || (t.wildcard = e.Query.wildcard.NONE), + t.wildcard & e.Query.wildcard.LEADING && t.term.charAt(0) != e.Query.wildcard && (t.term = '*' + t.term), + t.wildcard & e.Query.wildcard.TRAILING && t.term.slice(-1) != e.Query.wildcard && (t.term = '' + t.term + '*'), + 'presence' in t || (t.presence = e.Query.presence.OPTIONAL), + this.clauses.push(t), + this + ); + }), + (e.Query.prototype.isNegated = function () { + for (var t = 0; t < this.clauses.length; t++) + if (this.clauses[t].presence != e.Query.presence.PROHIBITED) return !1; + return !0; + }), + (e.Query.prototype.term = function (t, r) { + if (Array.isArray(t)) + return ( + t.forEach(function (t) { + this.term(t, e.utils.clone(r)); + }, this), + this + ); + var i = r || {}; + return (i.term = t.toString()), this.clause(i), this; + }), + (e.QueryParseError = function (e, t, r) { + (this.name = 'QueryParseError'), (this.message = e), (this.start = t), (this.end = r); + }), + (e.QueryParseError.prototype = new Error()), + (e.QueryLexer = function (e) { + (this.lexemes = []), + (this.str = e), + (this.length = e.length), + (this.pos = 0), + (this.start = 0), + (this.escapeCharPositions = []); + }), + (e.QueryLexer.prototype.run = function () { + for (var t = e.QueryLexer.lexText; t; ) t = t(this); + }), + (e.QueryLexer.prototype.sliceString = function () { + for (var e = [], t = this.start, r = this.pos, i = 0; i < this.escapeCharPositions.length; i++) + (r = this.escapeCharPositions[i]), e.push(this.str.slice(t, r)), (t = r + 1); + return e.push(this.str.slice(t, this.pos)), (this.escapeCharPositions.length = 0), e.join(''); + }), + (e.QueryLexer.prototype.emit = function (e) { + this.lexemes.push({ type: e, str: this.sliceString(), start: this.start, end: this.pos }), + (this.start = this.pos); + }), + (e.QueryLexer.prototype.escapeCharacter = function () { + this.escapeCharPositions.push(this.pos - 1), (this.pos += 1); + }), + (e.QueryLexer.prototype.next = function () { + if (this.pos >= this.length) return e.QueryLexer.EOS; + var t = this.str.charAt(this.pos); + return (this.pos += 1), t; + }), + (e.QueryLexer.prototype.width = function () { + return this.pos - this.start; + }), + (e.QueryLexer.prototype.ignore = function () { + this.start == this.pos && (this.pos += 1), (this.start = this.pos); + }), + (e.QueryLexer.prototype.backup = function () { + this.pos -= 1; + }), + (e.QueryLexer.prototype.acceptDigitRun = function () { + var t, r; + do (t = this.next()), (r = t.charCodeAt(0)); + while (r > 47 && r < 58); + t != e.QueryLexer.EOS && this.backup(); + }), + (e.QueryLexer.prototype.more = function () { + return this.pos < this.length; + }), + (e.QueryLexer.EOS = 'EOS'), + (e.QueryLexer.FIELD = 'FIELD'), + (e.QueryLexer.TERM = 'TERM'), + (e.QueryLexer.EDIT_DISTANCE = 'EDIT_DISTANCE'), + (e.QueryLexer.BOOST = 'BOOST'), + (e.QueryLexer.PRESENCE = 'PRESENCE'), + (e.QueryLexer.lexField = function (t) { + return t.backup(), t.emit(e.QueryLexer.FIELD), t.ignore(), e.QueryLexer.lexText; + }), + (e.QueryLexer.lexTerm = function (t) { + if ((t.width() > 1 && (t.backup(), t.emit(e.QueryLexer.TERM)), t.ignore(), t.more())) return e.QueryLexer.lexText; + }), + (e.QueryLexer.lexEditDistance = function (t) { + return t.ignore(), t.acceptDigitRun(), t.emit(e.QueryLexer.EDIT_DISTANCE), e.QueryLexer.lexText; + }), + (e.QueryLexer.lexBoost = function (t) { + return t.ignore(), t.acceptDigitRun(), t.emit(e.QueryLexer.BOOST), e.QueryLexer.lexText; + }), + (e.QueryLexer.lexEOS = function (t) { + t.width() > 0 && t.emit(e.QueryLexer.TERM); + }), + (e.QueryLexer.termSeparator = e.tokenizer.separator), + (e.QueryLexer.lexText = function (t) { + for (;;) { + var r = t.next(); + if (r == e.QueryLexer.EOS) return e.QueryLexer.lexEOS; + if (92 != r.charCodeAt(0)) { + if (':' == r) return e.QueryLexer.lexField; + if ('~' == r) return t.backup(), t.width() > 0 && t.emit(e.QueryLexer.TERM), e.QueryLexer.lexEditDistance; + if ('^' == r) return t.backup(), t.width() > 0 && t.emit(e.QueryLexer.TERM), e.QueryLexer.lexBoost; + if ('+' == r && 1 === t.width()) return t.emit(e.QueryLexer.PRESENCE), e.QueryLexer.lexText; + if ('-' == r && 1 === t.width()) return t.emit(e.QueryLexer.PRESENCE), e.QueryLexer.lexText; + if (r.match(e.QueryLexer.termSeparator)) return e.QueryLexer.lexTerm; + } else t.escapeCharacter(); + } + }), + (e.QueryParser = function (t, r) { + (this.lexer = new e.QueryLexer(t)), (this.query = r), (this.currentClause = {}), (this.lexemeIdx = 0); + }), + (e.QueryParser.prototype.parse = function () { + this.lexer.run(), (this.lexemes = this.lexer.lexemes); + for (var t = e.QueryParser.parseClause; t; ) t = t(this); + return this.query; + }), + (e.QueryParser.prototype.peekLexeme = function () { + return this.lexemes[this.lexemeIdx]; + }), + (e.QueryParser.prototype.consumeLexeme = function () { + var e = this.peekLexeme(); + return (this.lexemeIdx += 1), e; + }), + (e.QueryParser.prototype.nextClause = function () { + var e = this.currentClause; + this.query.clause(e), (this.currentClause = {}); + }), + (e.QueryParser.parseClause = function (t) { + var r = t.peekLexeme(); + if (void 0 != r) + switch (r.type) { + case e.QueryLexer.PRESENCE: + return e.QueryParser.parsePresence; + case e.QueryLexer.FIELD: + return e.QueryParser.parseField; + case e.QueryLexer.TERM: + return e.QueryParser.parseTerm; + default: + var i = 'expected either a field or a term, found ' + r.type; + throw (r.str.length >= 1 && (i += " with value '" + r.str + "'"), new e.QueryParseError(i, r.start, r.end)); + } + }), + (e.QueryParser.parsePresence = function (t) { + var r = t.consumeLexeme(); + if (void 0 != r) { + switch (r.str) { + case '-': + t.currentClause.presence = e.Query.presence.PROHIBITED; + break; + case '+': + t.currentClause.presence = e.Query.presence.REQUIRED; + break; + default: + var i = "unrecognised presence operator'" + r.str + "'"; + throw new e.QueryParseError(i, r.start, r.end); + } + var n = t.peekLexeme(); + if (void 0 == n) { + var i = 'expecting term or field, found nothing'; + throw new e.QueryParseError(i, r.start, r.end); + } + switch (n.type) { + case e.QueryLexer.FIELD: + return e.QueryParser.parseField; + case e.QueryLexer.TERM: + return e.QueryParser.parseTerm; + default: + var i = "expecting term or field, found '" + n.type + "'"; + throw new e.QueryParseError(i, n.start, n.end); + } + } + }), + (e.QueryParser.parseField = function (t) { + var r = t.consumeLexeme(); + if (void 0 != r) { + if (t.query.allFields.indexOf(r.str) == -1) { + var i = t.query.allFields + .map(function (e) { + return "'" + e + "'"; + }) + .join(', '), + n = "unrecognised field '" + r.str + "', possible fields: " + i; + throw new e.QueryParseError(n, r.start, r.end); + } + t.currentClause.fields = [r.str]; + var s = t.peekLexeme(); + if (void 0 == s) { + var n = 'expecting term, found nothing'; + throw new e.QueryParseError(n, r.start, r.end); + } + switch (s.type) { + case e.QueryLexer.TERM: + return e.QueryParser.parseTerm; + default: + var n = "expecting term, found '" + s.type + "'"; + throw new e.QueryParseError(n, s.start, s.end); + } + } + }), + (e.QueryParser.parseTerm = function (t) { + var r = t.consumeLexeme(); + if (void 0 != r) { + (t.currentClause.term = r.str.toLowerCase()), r.str.indexOf('*') != -1 && (t.currentClause.usePipeline = !1); + var i = t.peekLexeme(); + if (void 0 == i) return void t.nextClause(); + switch (i.type) { + case e.QueryLexer.TERM: + return t.nextClause(), e.QueryParser.parseTerm; + case e.QueryLexer.FIELD: + return t.nextClause(), e.QueryParser.parseField; + case e.QueryLexer.EDIT_DISTANCE: + return e.QueryParser.parseEditDistance; + case e.QueryLexer.BOOST: + return e.QueryParser.parseBoost; + case e.QueryLexer.PRESENCE: + return t.nextClause(), e.QueryParser.parsePresence; + default: + var n = "Unexpected lexeme type '" + i.type + "'"; + throw new e.QueryParseError(n, i.start, i.end); + } + } + }), + (e.QueryParser.parseEditDistance = function (t) { + var r = t.consumeLexeme(); + if (void 0 != r) { + var i = parseInt(r.str, 10); + if (isNaN(i)) { + var n = 'edit distance must be numeric'; + throw new e.QueryParseError(n, r.start, r.end); + } + t.currentClause.editDistance = i; + var s = t.peekLexeme(); + if (void 0 == s) return void t.nextClause(); + switch (s.type) { + case e.QueryLexer.TERM: + return t.nextClause(), e.QueryParser.parseTerm; + case e.QueryLexer.FIELD: + return t.nextClause(), e.QueryParser.parseField; + case e.QueryLexer.EDIT_DISTANCE: + return e.QueryParser.parseEditDistance; + case e.QueryLexer.BOOST: + return e.QueryParser.parseBoost; + case e.QueryLexer.PRESENCE: + return t.nextClause(), e.QueryParser.parsePresence; + default: + var n = "Unexpected lexeme type '" + s.type + "'"; + throw new e.QueryParseError(n, s.start, s.end); + } + } + }), + (e.QueryParser.parseBoost = function (t) { + var r = t.consumeLexeme(); + if (void 0 != r) { + var i = parseInt(r.str, 10); + if (isNaN(i)) { + var n = 'boost must be numeric'; + throw new e.QueryParseError(n, r.start, r.end); + } + t.currentClause.boost = i; + var s = t.peekLexeme(); + if (void 0 == s) return void t.nextClause(); + switch (s.type) { + case e.QueryLexer.TERM: + return t.nextClause(), e.QueryParser.parseTerm; + case e.QueryLexer.FIELD: + return t.nextClause(), e.QueryParser.parseField; + case e.QueryLexer.EDIT_DISTANCE: + return e.QueryParser.parseEditDistance; + case e.QueryLexer.BOOST: + return e.QueryParser.parseBoost; + case e.QueryLexer.PRESENCE: + return t.nextClause(), e.QueryParser.parsePresence; + default: + var n = "Unexpected lexeme type '" + s.type + "'"; + throw new e.QueryParseError(n, s.start, s.end); + } + } + }), + (function (e, t) { + 'function' == typeof define && define.amd + ? define(t) + : 'object' == typeof exports + ? (module.exports = t()) + : (e.lunr = t()); + })(this, function () { + return e; + }); +})(); diff --git a/docs/assets/plugins/search/search.css b/docs/assets/plugins/search/search.css new file mode 100644 index 000000000..e595f6012 --- /dev/null +++ b/docs/assets/plugins/search/search.css @@ -0,0 +1,172 @@ +body.site-search-visible { + overflow: hidden; +} + +.sidebar .search-box { + margin: 1.25rem 26px; +} + +.sidebar .search-box kbd { + margin-top: 2px; +} + +/* Site search */ +.site-search { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 1000; +} + +.site-search[hidden] { + display: none; +} + +.site-search__overlay { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgb(var(--sl-overlay-background-color) / var(--sl-overlay-opacity)); + z-index: -1; +} + +.site-search__panel { + display: flex; + flex-direction: column; + max-width: 460px; + max-height: calc(100vh - 20rem); + background-color: rgb(var(--sl-color-neutral-0)); + border-radius: var(--sl-border-radius-large); + box-shadow: var(--sl-shadow-x-large); + margin: 10rem auto; +} + +@media screen and (max-width: 900px) { + .site-search__panel { + max-width: 100%; + max-height: calc(92vh - 120px); /* allow iOS browser chrome */ + margin: 4vh var(--sl-spacing-medium); + } +} + +.site-search__input::part(base) { + border: none; + background: transparent; + border-radius: var(--sl-border-radius-large); +} + +.site-search__input:focus-within::part(base) { + outline: none; + box-shadow: none; +} + +.site-search__input { + --sl-input-height-large: 4rem; +} + +.site-search__body { + flex: 1 1 auto; + overflow: auto; +} + +.site-search--has-results .site-search__body { + border-top: solid 1px rgb(var(--sl-color-neutral-200)); +} + +.site-search__results { + display: none; + line-height: var(--sl-line-height-dense); + list-style: none; + padding: var(--sl-spacing-x-small) 0; + margin: 0; +} + +.site-search--has-results .site-search__results { + display: block; +} + +.site-search__results a { + display: block; + text-decoration: none; + padding: var(--sl-spacing-x-small) var(--sl-spacing-large); +} + +.site-search__results li a:hover, +.site-search__results li a:hover small { + background-color: rgb(var(--sl-color-neutral-100)); +} + +.site-search__results li[aria-selected='true'] a, +.site-search__results li[aria-selected='true'] a small, +.site-search__results li[aria-selected='true'] a sl-icon { + outline: none; + color: rgb(var(--sl-color-neutral-0)); + background-color: rgb(var(--sl-color-primary-600)); +} + +.site-search__results h3 { + font-weight: var(--sl-font-weight-semibold); + margin: 0; +} + +.site-search__results small { + display: block; + color: rgb(var(--sl-color-neutral-600)); +} + +.site-search__result { + padding: 0; + margin: 0; +} + +.site-search__result a { + display: flex; + align-items: center; + gap: var(--sl-spacing-medium); +} + +.site-search__result-icon { + flex: 0 0 auto; + display: flex; + color: rgb(var(--sl-color-neutral-400)); + font-size: var(--sl-font-size-x-large); +} + +.site-search__result-description { + flex: 1 1 auto; +} + +.site-search__empty { + display: none; + border-top: solid 1px rgb(var(--sl-color-neutral-200)); + text-align: center; + padding: var(--sl-spacing-x-large); +} + +.site-search--no-results .site-search__empty { + display: block; +} + +.site-search__footer { + display: flex; + justify-content: center; + gap: var(--sl-spacing-large); + border-top: solid 1px rgb(var(--sl-color-neutral-200)); + border-bottom-left-radius: inherit; + border-bottom-right-radius: inherit; + padding: var(--sl-spacing-medium); +} + +.site-search__footer small { + color: rgb(var(--sl-color-neutral-700)); +} + +@media screen and (max-width: 900px) { + .site-search__footer { + display: none; + } +} diff --git a/docs/assets/plugins/search/search.js b/docs/assets/plugins/search/search.js new file mode 100644 index 000000000..160cb5cdc --- /dev/null +++ b/docs/assets/plugins/search/search.js @@ -0,0 +1,293 @@ +(() => { + if (!window.$docsify) { + throw new Error('Docsify must be loaded before installing this plugin.'); + } + + window.$docsify.plugins.push((hook, vm) => { + // Append the search box to the sidebar + hook.mounted(function () { + const appName = document.querySelector('.sidebar .app-name'); + const searchBox = document.createElement('div'); + searchBox.classList.add('search-box'); + searchBox.innerHTML = ` + + + / + + `; + const searchBoxInput = searchBox.querySelector('sl-input'); + + appName.insertAdjacentElement('afterend', searchBox); + + // Show the search panel when the search is clicked + searchBoxInput.addEventListener('mousedown', event => { + event.preventDefault(); + show(); + }); + + // Show the search panel when a key is pressed + searchBoxInput.addEventListener('keydown', event => { + if (event.key === 'Tab') { + return; + } + + // Pass the character that was typed through to the search input + if (event.key.length === 1) { + event.preventDefault(); + input.value = event.key; + show(); + } + }); + }); + + // Append the search panel to the body + const siteSearch = document.createElement('div'); + siteSearch.classList.add('site-search'); + siteSearch.hidden = true; + siteSearch.innerHTML = ` +
+
+
+ + + +
+
+
    +
    No results found.
    +
    +
    + navigate + select + esc close +
    +
    + `; + document.body.append(siteSearch); + + const searchButtons = [...document.querySelectorAll('[data-site-search]')]; + const overlay = siteSearch.querySelector('.site-search__overlay'); + const panel = siteSearch.querySelector('.site-search__panel'); + const input = siteSearch.querySelector('.site-search__input'); + const results = siteSearch.querySelector('.site-search__results'); + const animationDuration = 150; + const searchDebounce = 200; + let isShowing = false; + let searchTimeout; + let searchIndex; + let map; + + // Load search data + const searchData = fetch('../../../search.json') + .then(res => res.json()) + .then(data => { + searchIndex = lunr.Index.load(data.searchIndex); + map = data.map; + }); + + async function show() { + isShowing = true; + document.body.classList.add('site-search-visible'); + siteSearch.hidden = false; + input.focus(); + updateResults(); + + await Promise.all([ + panel.animate( + [ + { opacity: 0, transform: 'scale(.9)' }, + { opacity: 1, transform: 'scale(1)' } + ], + { duration: animationDuration } + ).finished, + overlay.animate([{ opacity: 0 }, { opacity: 1 }], { duration: animationDuration }).finished + ]); + + document.addEventListener('mousedown', handleDocumentMouseDown); + document.addEventListener('keydown', handleDocumentKeyDown); + document.addEventListener('focusin', handleDocumentFocusIn); + } + + async function hide() { + isShowing = false; + document.body.classList.remove('site-search-visible'); + + await Promise.all([ + panel.animate( + [ + { opacity: 1, transform: 'scale(1)' }, + { opacity: 0, transform: 'scale(.9)' } + ], + { duration: animationDuration } + ).finished, + overlay.animate([{ opacity: 1 }, { opacity: 0 }], { duration: animationDuration }).finished + ]); + + siteSearch.hidden = true; + input.value = ''; + updateResults(); + + document.removeEventListener('mousedown', handleDocumentMouseDown); + document.removeEventListener('keydown', handleDocumentKeyDown); + document.removeEventListener('focusin', handleDocumentFocusIn); + } + + function handleInput() { + // Debounce search queries + clearTimeout(searchTimeout); + searchTimeout = setTimeout(() => updateResults(input.value), searchDebounce); + } + + function handleDocumentFocusIn(event) { + // Close when focus leaves the panel + if (event.target.closest('.site-search__panel') !== panel) { + hide(); + } + } + + function handleDocumentMouseDown(event) { + // Close when clicking outside of the panel + if (event.target.closest('.site-search__overlay') === overlay) { + hide(); + } + } + + function handleDocumentKeyDown(event) { + // Close when pressing escape + if (event.key === 'Escape') { + event.preventDefault(); + hide(); + return; + } + + // Handle keyboard selections + if (['ArrowDown', 'ArrowUp', 'Home', 'End', 'Enter'].includes(event.key)) { + event.preventDefault(); + + const currentEl = results.querySelector('[aria-selected="true"]'); + const items = [...results.querySelectorAll('li')]; + const index = items.indexOf(currentEl); + let nextEl; + + if (items.length === 0) { + return; + } + + switch (event.key) { + case 'ArrowUp': + nextEl = items[Math.max(0, index - 1)]; + break; + case 'ArrowDown': + nextEl = items[Math.min(items.length - 1, index + 1)]; + break; + case 'Home': + nextEl = items[0]; + break; + case 'End': + nextEl = items[items.length - 1]; + break; + case 'Enter': + currentEl?.querySelector('a')?.click(); + break; + } + + // Update the selected item + items.map(item => { + if (item === nextEl) { + item.setAttribute('aria-selected', 'true'); + nextEl.scrollIntoView({ block: 'nearest' }); + } else { + item.setAttribute('aria-selected', 'false'); + } + }); + + return; + } + } + + async function updateResults(query = '') { + try { + await searchIndex; + + const hasQuery = query.length > 0; + let matches = hasQuery ? searchIndex.search(`${query}`) : []; + + // Fall back to a fuzzy search if no matches are found + if (matches.length === 0 && hasQuery) { + matches = searchIndex.search(`${query}~2`); + } + + let hasResults = hasQuery && matches.length > 0; + siteSearch.classList.toggle('site-search--has-results', hasQuery && hasResults); + siteSearch.classList.toggle('site-search--no-results', hasQuery && !hasResults); + panel.setAttribute('aria-expanded', hasQuery && hasResults ? 'true' : 'false'); + + results.innerHTML = ''; + + matches.map((match, index) => { + const page = map[match.ref]; + const li = document.createElement('li'); + const a = document.createElement('a'); + let icon = 'file-text'; + + if (page.url.includes('getting-started/')) icon = 'lightbulb'; + if (page.url.includes('resources/')) icon = 'book'; + if (page.url.includes('components/')) icon = 'puzzle'; + if (page.url.includes('tokens/')) icon = 'palette2'; + if (page.url.includes('utilities/')) icon = 'wrench'; + if (page.url.includes('tutorials/')) icon = 'joystick'; + + a.href = $docsify.routerMode === 'hash' ? `/#/${page.url}` : `/${page.url}`; + a.innerHTML = ` +
    + +
    +
    +

    ${page.title}

    + ${page.url} +
    + `; + + li.classList.add('site-search__result'); + li.setAttribute('aria-selected', index === 0 ? 'true' : 'false'); + li.appendChild(a); + results.appendChild(li); + }); + } catch { + // Ignore query errors as the user types + } + } + + // Show the search panel slash is pressed outside of a form element + document.addEventListener('keydown', event => { + if ( + !isShowing && + event.key === '/' && + !event.composedPath().some(el => ['input', 'textarea'].includes(el?.tagName?.toLowerCase())) + ) { + event.preventDefault(); + show(); + } + }); + + input.addEventListener('sl-input', handleInput); + + // Close when a result is selected + results.addEventListener('click', event => { + if (event.target.closest('a')) { + hide(); + } + }); + }); +})(); diff --git a/docs/assets/plugins/sidebar/sidebar.js b/docs/assets/plugins/sidebar/sidebar.js deleted file mode 100644 index 1f8c37692..000000000 --- a/docs/assets/plugins/sidebar/sidebar.js +++ /dev/null @@ -1,14 +0,0 @@ -(() => { - if (!window.$docsify) { - throw new Error('Docsify must be loaded before installing this plugin.'); - } - - window.$docsify.plugins.push((hook, vm) => { - hook.mounted(function () { - // Move search below the app name - const appName = document.querySelector('.sidebar .app-name'); - const search = document.querySelector('.sidebar .search'); - appName.insertAdjacentElement('afterend', search); - }); - }); -})(); diff --git a/docs/assets/plugins/theme-picker/theme-picker.css b/docs/assets/plugins/theme-picker/theme-picker.css new file mode 100644 index 000000000..f0fa482dd --- /dev/null +++ b/docs/assets/plugins/theme-picker/theme-picker.css @@ -0,0 +1,29 @@ +.theme-picker { + position: fixed; + top: 1rem; + right: 1rem; + z-index: 30; +} + +.theme-picker:not(:defined) { + display: none; +} + +.theme-picker sl-menu-label { + white-space: nowrap; +} + +.theme-picker sl-menu-label kbd { + margin-left: 0.5rem; +} + +@media screen and (max-width: 768px) { + .theme-picker { + top: 0.5rem; + right: 0.5rem; + } + + .theme-picker sl-menu-label { + display: none; + } +} diff --git a/docs/assets/plugins/theme-picker/theme-picker.js b/docs/assets/plugins/theme-picker/theme-picker.js new file mode 100644 index 000000000..bce337ef4 --- /dev/null +++ b/docs/assets/plugins/theme-picker/theme-picker.js @@ -0,0 +1,84 @@ +(() => { + if (!window.$docsify) { + throw new Error('Docsify must be loaded before installing this plugin.'); + } + + window.$docsify.plugins.push((hook, vm) => { + hook.mounted(function () { + function getTheme() { + return localStorage.getItem('theme') || 'auto'; + } + + function isDark() { + if (theme === 'auto') { + return window.matchMedia('(prefers-color-scheme: dark)').matches; + } else { + return theme === 'dark'; + } + } + + function setTheme(newTheme) { + const noTransitions = Object.assign(document.createElement('style'), { + textContent: '* { transition: none !important; }' + }); + + theme = newTheme; + localStorage.setItem('theme', theme); + + // Update the UI + [...menu.querySelectorAll('sl-menu-item')].map(item => (item.checked = item.getAttribute('value') === theme)); + menuIcon.name = isDark() ? 'moon' : 'sun'; + + // Toggle the dark mode class without transitions + document.body.appendChild(noTransitions); + requestAnimationFrame(() => { + document.documentElement.classList.toggle('sl-theme-dark', isDark()); + requestAnimationFrame(() => document.body.removeChild(noTransitions)); + }); + } + + let theme = getTheme(); + + // Generate the theme picker dropdown + const dropdown = document.createElement('sl-dropdown'); + dropdown.classList.add('theme-picker'); + dropdown.innerHTML = ` + + + + + Toggle \\ + Light + Dark + + Auto + + `; + document.querySelector('.sidebar-toggle').insertAdjacentElement('afterend', dropdown); + + // Listen for selections + const menu = dropdown.querySelector('sl-menu'); + const menuIcon = dropdown.querySelector('sl-icon'); + menu.addEventListener('sl-select', event => setTheme(event.detail.item.value)); + + // Update the theme when the preference changes + window.matchMedia('(prefers-color-scheme: dark)').addListener(event => setTheme(theme)); + + // Toggle themes when pressing backslash + document.addEventListener('keydown', event => { + if ( + event.key === '\\' && + !event.composedPath().some(el => ['input', 'textarea'].includes(el?.tagName?.toLowerCase())) + ) { + event.preventDefault(); + + setTheme(isDark() ? 'light' : 'dark'); + show(); + } + }); + + // Set the intial theme and sync the UI + setTheme(theme); + }); + }); +})(); diff --git a/docs/assets/plugins/theme/theme.css b/docs/assets/plugins/theme/theme.css deleted file mode 100644 index 4855457f3..000000000 --- a/docs/assets/plugins/theme/theme.css +++ /dev/null @@ -1,13 +0,0 @@ -.theme-toggle { - position: fixed; - top: 0.5rem; - right: 0.5rem; - z-index: 100; -} - -@media screen and (max-width: 768px) { - .theme-toggle { - top: 0.25rem; - right: 0.25rem; - } -} diff --git a/docs/assets/plugins/theme/theme.js b/docs/assets/plugins/theme/theme.js deleted file mode 100644 index 2c4dd1d52..000000000 --- a/docs/assets/plugins/theme/theme.js +++ /dev/null @@ -1,41 +0,0 @@ -(() => { - if (!window.$docsify) { - throw new Error('Docsify must be loaded before installing this plugin.'); - } - - window.$docsify.plugins.push((hook, vm) => { - hook.mounted(function () { - let isDark = localStorage.getItem('theme') === 'sl-theme-dark'; - const sidebarToggle = document.querySelector('.sidebar-toggle'); - const noTransitions = Object.assign(document.createElement('style'), { - textContent: '* { transition: none !important; }' - }); - const toggle = Object.assign(document.createElement('sl-icon-button'), { - name: isDark ? 'sun' : 'moon', - label: 'Toggle dark mode' - }); - toggle.classList.add('theme-toggle'); - - // Set initial theme - if (isDark) { - document.body.classList.add('sl-theme-dark'); - } - - // Toggle theme - toggle.addEventListener('click', () => { - isDark = !isDark; - isDark ? localStorage.setItem('theme', 'sl-theme-dark') : localStorage.removeItem('theme'); - toggle.name = isDark ? 'sun' : 'moon'; - - // Disable transitions as the theme changes - document.body.appendChild(noTransitions); - requestAnimationFrame(() => { - document.body.classList.toggle('sl-theme-dark', isDark); - requestAnimationFrame(() => document.body.removeChild(noTransitions)); - }); - }); - - sidebarToggle.insertAdjacentElement('afterend', toggle); - }); - }); -})(); diff --git a/docs/assets/styles/demos.css b/docs/assets/styles/demos.css deleted file mode 100644 index d5e89c42c..000000000 --- a/docs/assets/styles/demos.css +++ /dev/null @@ -1,60 +0,0 @@ -/* Color demo */ -.color-demo { - width: 4rem; - height: 2rem; - border-radius: var(--sl-border-radius-small); - box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.33); -} - -/* Border radius demo */ -.border-radius-demo { - width: 3rem; - height: 3rem; - background: var(--sl-color-primary-500); -} - -/* Transition demo */ -.transition-demo { - position: relative; - background: var(--sl-color-gray-200); - width: 8rem; - height: 2rem; -} - -.transition-demo:after { - content: ''; - position: absolute; - background-color: var(--sl-color-primary-500); - top: 0; - left: 0; - width: 0; - height: 100%; - transition-duration: inherit; - transition-property: width; -} - -.transition-demo:hover:after { - width: 100%; -} - -.sl-theme-dark .transition-demo { - background: var(--sl-color-gray-800); -} - -/* Spacing demo */ -.spacing-demo { - width: 100px; - background: var(--sl-color-primary-500); -} - -/* Elevation dmeo */ -.elevation-demo { - background: var(--sl-color-white); - border-radius: 3px; - width: 4rem; - height: 4rem; -} - -.sl-theme-dark .elevation-demo { - background-color: var(--sl-color-gray-800); -} diff --git a/docs/assets/styles/docs-dark.css b/docs/assets/styles/docs-dark.css deleted file mode 100644 index d280e22ce..000000000 --- a/docs/assets/styles/docs-dark.css +++ /dev/null @@ -1,191 +0,0 @@ -/* Elevation tokens */ -.sl-theme-dark { - --sl-shadow-x-small: 0 1px 0 #6b72800d; - --sl-shadow-small: 0 1px 2px #6b72801a; - --sl-shadow-medium: 0 2px 4px #6b72801a; - --sl-shadow-large: 0 2px 8px #6b72801a; - --sl-shadow-x-large: 0 4px 16px #6b72801a; -} - -.sl-theme-dark { - background: var(--sl-color-gray-900); - color: var(--sl-color-gray-200); -} - -/* Sidebar **/ -.sl-theme-dark .sidebar { - background: var(--sl-color-gray-900); - border-right-color: var(--sl-color-gray-900); -} - -.sl-theme-dark .sidebar li > p { - color: var(--sl-color-white); - border-bottom-color: var(--sl-color-gray-800); -} - -.sl-theme-dark .sidebar-toggle { - background-color: var(--sl-color-gray-900); -} - -.sl-theme-dark .docsify-pagination-container { - border-top-color: var(--sl-color-gray-800) !important; -} - -/* Search */ -.sl-theme-dark .sidebar .search input[type='search'] { - background: var(--sl-input-background-color); - border-color: var(--sl-input-border-color); - color: var(--sl-input-color); -} - -.sl-theme-dark .sidebar .search input[type='search']:hover { - border-color: var(--sl-input-border-color-hover); -} - -.sl-theme-dark .sidebar .search input[type='search']:focus { - border-color: var(--sl-input-border-color-focus); -} - -.sl-theme-dark .sidebar .clear-button { - color: var(--sl-color-gray-700); -} - -.sl-theme-dark .sidebar .clear-button svg circle { - fill: currentColor; -} - -/* Content */ -.sl-theme-dark .component-header { - border-bottom-color: var(--sl-color-gray-800); -} - -.sl-theme-dark .anchor span { - color: var(--sl-color-white); -} - -.sl-theme-dark .markdown-section h2 { - border-bottom-color: var(--sl-color-gray-800); -} - -.sl-theme-dark .markdown-section blockquote { - border-left-color: var(--sl-color-gray-800); -} - -.sl-theme-dark .markdown-section kbd { - border-color: var(--sl-color-gray-800); -} - -/* Tables */ -.sl-theme-dark .markdown-section tr:nth-child(2n) { - background: var(--sl-color-gray-950); -} - -.sl-theme-dark .markdown-section td { - border-top-color: var(--sl-color-gray-800); - border-bottom-color: var(--sl-color-gray-800); -} - -/* Tips & warnings */ -.sl-theme-dark .markdown-section p.tip, -.sl-theme-dark .markdown-section p.warn { - background-color: var(--sl-color-gray-950); -} - -.sl-theme-dark .markdown-section p.tip:before, -.sl-theme-dark .markdown-section p.warn:before { - color: var(--sl-color-gray-900); -} - -.sl-theme-dark .markdown-section p.tip code, -.sl-theme-dark .markdown-section p.warn code { - background-color: var(--sl-color-gray-800); -} - -/* Code */ -.sl-theme-dark .markdown-section code { - background: var(--sl-color-gray-950); -} - -/* Code blocks */ -.sl-theme-dark .markdown-section pre, -.sl-theme-dark .code-block__source { - background-color: var(--sl-color-gray-800); -} - -.sl-theme-dark .markdown-section pre > code { - color: var(--sl-color-gray-200); -} - -.sl-theme-dark .markdown-section pre .token.comment { - color: var(--sl-color-gray-600); -} - -.sl-theme-dark .markdown-section pre .token.prolog, -.sl-theme-dark .markdown-section pre .token.doctype, -.sl-theme-dark .markdown-section pre .token.cdata, -.sl-theme-dark .markdown-section pre .token.operator { - color: var(--sl-color-gray-300); -} - -.sl-theme-dark .markdown-section pre .token.property, -.sl-theme-dark .markdown-section pre .token.keyword, -.sl-theme-dark .markdown-section pre .token.tag, -.sl-theme-dark .markdown-section pre .token.url { - color: var(--sl-color-primary-400); -} - -.sl-theme-dark .markdown-section pre .token.symbol, -.sl-theme-dark .markdown-section pre .token.deleted { - color: #f92672; -} - -.sl-theme-dark .markdown-section pre .token.boolean, -.sl-theme-dark .markdown-section pre .token.constant, -.sl-theme-dark .markdown-section pre .token.selector, -.sl-theme-dark .markdown-section pre .token.attr-name, -.sl-theme-dark .markdown-section pre .token.string, -.sl-theme-dark .markdown-section pre .token.char, -.sl-theme-dark .markdown-section pre .token.builtin, -.sl-theme-dark .markdown-section pre .token.inserted { - color: var(--sl-color-success-400); -} - -.sl-theme-dark .markdown-section pre .token.atrule, -.sl-theme-dark .markdown-section pre .token.attr-value, -.sl-theme-dark .markdown-section pre .token.number, -.sl-theme-dark .markdown-section pre .token.variable { - color: #c380ff; -} - -.sl-theme-dark .markdown-section pre .token.function, -.sl-theme-dark .markdown-section pre .token.class-name { - color: #ffbb4d; -} - -.sl-theme-dark .markdown-section pre .token.regex { - color: #f8bd5b; -} - -.sl-theme-dark .markdown-section pre .token.important { - color: #fd495f; -} - -/* Repo buttons */ -.sl-theme-dark .repo-button { - background-color: var(--sl-color-gray-900); - border-color: var(--sl-color-gray-800); - color: var(--sl-color-gray-200); -} - -.sl-theme-dark .repo-button--github sl-icon { - color: var(--sl-color-white); -} - -.sl-theme-dark .repo-button:hover { - background-color: var(--sl-color-gray-900); - border: solid 1px var(--sl-color-gray-700); -} - -.sl-theme-dark .repo-button:focus { - border-color: var(--sl-color-primary-500); -} diff --git a/docs/assets/styles/docs.css b/docs/assets/styles/docs.css index 5ebc2ca60..e6afa3123 100644 --- a/docs/assets/styles/docs.css +++ b/docs/assets/styles/docs.css @@ -13,12 +13,17 @@ body { font-size: var(--sl-font-size-medium); font-weight: var(--sl-font-weight-normal); letter-spacing: var(--sl-letter-spacing-normal); - color: var(--sl-color-gray-800); + background-color: rgb(var(--sl-surface-base)); + color: rgb(var(--sl-color-neutral-800)); line-height: var(--sl-line-height-normal); } a { - color: var(--sl-color-primary-500); + color: rgb(var(--sl-color-primary-600)); +} + +a:hover { + color: rgb(var(--sl-color-primary-700)); } strong { @@ -27,19 +32,18 @@ strong { /* Sidebar */ .sidebar { - background: var(--sl-color-white); - border-right: solid 1px var(--sl-color-gray-200); + background-color: rgb(var(--sl-surface-base)); + border-right: solid 1px rgb(var(--sl-color-neutral-200)); } .sidebar .app-name { padding: 0 1.5rem; - margin-top: 1.5rem; } .sidebar-version { font-size: var(--sl-font-size-x-small); font-weight: var(--sl-font-weight-normal); - color: var(--sl-color-gray-400); + color: rgb(var(--sl-color-neutral-500)); text-align: right; padding: 0 var(--sl-spacing-small); margin: -1.25rem 0 0.6rem 0; @@ -50,76 +54,6 @@ strong { margin-top: 0; } -/* Search */ -.sidebar .search { - position: relative; - border: none; -} - -.sidebar .search input[type='search'] { - border: solid 1px var(--sl-input-border-color); - border-radius: var(--sl-border-radius-pill); - padding-left: 1rem; - padding-right: 2rem; - margin: 0 1.25rem; - transition: var(--sl-transition-fast) color, var(--sl-transition-fast) border, var(--sl-transition-fast) box-shadow; -} - -.sidebar .search input[type='search']:hover { - border-color: var(--sl-input-border-color-hover); -} - -.sidebar .search input[type='search']:focus { - box-shadow: 0 0 0 var(--sl-focus-ring-width) var(--sl-focus-ring-color-primary); - border-color: var(--sl-input-border-color-focus); - outline: none; -} - -.sidebar .input-wrap { - position: relative; - width: 100%; - padding: 0 0.25rem; -} - -.sidebar .clear-button { - position: absolute; - right: 30px; - top: 7px; - width: 22px !important; - height: 22px !important; -} - -.sidebar .clear-button svg { - transform: scale(0.75) !important; -} - -.sidebar .clear-button:focus { - outline: none; -} - -.search .results-panel { - margin-top: 1rem; -} - -.search .matching-post { - border-bottom: solid 1px var(--sl-color-gray-500) !important; - padding: 0.25rem 1.5rem; -} - -.search .matching-post a { - display: block; - border-radius: inherit; - padding: 0.5rem; -} - -.search .matching-post h2 { - margin-bottom: 0; -} - -.search .matching-post p { - margin-top: 0; -} - /* Sidebar toggle */ .sidebar-toggle { top: 0.25rem; @@ -127,13 +61,21 @@ strong { width: 2rem; height: 2rem; border-radius: var(--sl-border-radius-medium); - background-color: var(--sl-color-white); + background-color: rgb(var(--sl-surface-base)); padding: 0.5rem; } +.sidebar-toggle:hover .sidebar-toggle-button { + opacity: 1; +} + +.sidebar-toggle:active .sidebar-toggle-button span { + background-color: rgb(var(--sl-color-primary-600)); +} + .sidebar-toggle:focus { outline: none; - box-shadow: 0 0 0 var(--sl-focus-ring-width) var(--sl-focus-ring-color-primary); + box-shadow: var(--sl-focus-ring); } .sidebar-toggle span:last-child { @@ -168,12 +110,12 @@ strong { .sidebar-nav li.collapse > a, .sidebar-nav li.active > a { - color: var(--sl-color-primary-500); + color: rgb(var(--sl-color-primary-600)); } .sidebar li > p { font-weight: var(--sl-font-weight-bold); - border-bottom: solid 1px var(--sl-color-gray-200); + border-bottom: solid 1px rgb(var(--sl-color-neutral-200)); margin: 0 0.75rem 0.5rem 0; } @@ -218,6 +160,11 @@ strong { max-width: 22rem; } +.markdown-section .splash-start h1:first-of-type { + font-size: var(--sl-font-size-large); + margin: 0 0 0.5rem 0; +} + @media screen and (max-width: 1040px) { .splash { display: block; @@ -253,9 +200,13 @@ strong { overflow-anchor: none; } +.anchor span { + color: rgb(var(--sl-color-neutral-1000)); +} + .markdown-section blockquote { position: relative; - border-left: solid 4px var(--sl-color-gray-200); + border-left: solid 4px rgb(var(--sl-color-neutral-200)); font-style: italic; padding: 1rem 1.5rem; margin: 0 0 1rem 0; @@ -279,7 +230,13 @@ strong { } .docsify-pagination-container { - border-top-color: var(--sl-color-gray-200) !important; + border-top-color: rgb(var(--sl-color-neutral-200)) !important; +} + +.pagination-item-label, +.pagination-item-subtitle, +.pagination-item-title { + opacity: 1 !important; } .markdown-section h1, @@ -293,12 +250,12 @@ strong { } .markdown-section h1 { - font-size: var(--sl-font-size-xx-large); + font-size: var(--sl-font-size-2x-large); } .markdown-section h2 { font-size: var(--sl-font-size-x-large); - border-bottom: solid 1px var(--sl-color-gray-200); + border-bottom: solid 1px rgb(var(--sl-color-neutral-200)); margin-top: 2rem; } @@ -329,23 +286,26 @@ strong { .markdown-section code { font-family: var(--sl-font-mono); font-size: 87.5%; - background: var(--sl-color-gray-50); + background-color: rgb(var(--sl-color-neutral-50)); border-radius: var(--sl-border-radius-small); padding: 2px 4px; } +kbd, .markdown-section kbd { font-family: var(--sl-font-mono); font-size: 87.5%; + background-color: rgb(var(--sl-color-neutral-50)); border-radius: var(--sl-border-radius-small); - border: solid 1px var(--sl-color-gray-200); - padding: 2px 4px; + border: solid 1px rgb(var(--sl-color-neutral-200)); + box-shadow: inset 0 1px 0 rgb(var(--sl-color-neutral-0)); + padding: 2px 5px; } /* Code blocks */ .markdown-section pre { position: relative; - background: var(--sl-color-gray-50); + background-color: rgb(var(--sl-color-neutral-50)); border-radius: var(--sl-border-radius-medium); } @@ -353,7 +313,7 @@ strong { display: block; background: none; border-radius: 0; - color: var(--sl-color-gray-700); + color: rgb(var(--sl-color-neutral-800)); padding: var(--sl-spacing-medium); overflow: auto; hyphens: none; @@ -361,18 +321,18 @@ strong { } .markdown-section pre .token.comment { - color: var(--sl-color-gray-400); + color: rgb(var(--sl-color-neutral-500)); } .markdown-section pre .token.prolog, .markdown-section pre .token.doctype, .markdown-section pre .token.cdata, .markdown-section pre .token.operator { - color: var(--sl-color-gray-600); + color: rgb(var(--sl-color-neutral-600)); } .markdown-section pre .token.punctuation { - color: var(--sl-color-gray-500); + color: rgb(var(--sl-color-neutral-600)); } .namespace { @@ -383,12 +343,12 @@ strong { .markdown-section pre .token.keyword, .markdown-section pre .token.tag, .markdown-section pre .token.url { - color: var(--sl-color-primary-500); + color: rgb(var(--sl-color-sky-600)); } .markdown-section pre .token.symbol, .markdown-section pre .token.deleted { - color: #f92672; + color: rgb(var(--sl-color-pink-600)); } .markdown-section pre .token.boolean, @@ -399,27 +359,24 @@ strong { .markdown-section pre .token.char, .markdown-section pre .token.builtin, .markdown-section pre .token.inserted { - color: var(--sl-color-success-600); + color: rgb(var(--sl-color-emerald-600)); } .markdown-section pre .token.atrule, .markdown-section pre .token.attr-value, .markdown-section pre .token.number, .markdown-section pre .token.variable { - color: #9013fe; + color: rgb(var(--sl-color-violet-600)); } .markdown-section pre .token.function, -.markdown-section pre .token.class-name { - color: #eb9200; -} - +.markdown-section pre .token.class-name, .markdown-section pre .token.regex { - color: #f5a623; + color: rgb(var(--sl-color-orange-600)); } .markdown-section pre .token.important { - color: #d0021b; + color: rgb(var(--sl-color-red-600)); } .markdown-section pre .token.important, @@ -432,6 +389,16 @@ strong { } /* Tables */ +.table-wrapper { + overflow-x: auto; +} + +@media screen and (max-width: 1200px) { + .table-wrapper table { + min-width: 800px; + } +} + .markdown-section table { display: table; margin-bottom: 1.5rem; @@ -442,7 +409,7 @@ strong { } .markdown-section tr:nth-child(2n) { - background: var(--sl-color-gray-50); + background: rgb(var(--sl-color-neutral-50)); } .markdown-section th { @@ -452,8 +419,8 @@ strong { } .markdown-section td { - border-top: solid 1px var(--sl-color-gray-200); - border-bottom: solid 1px var(--sl-color-gray-200); + border-top: solid 1px rgb(var(--sl-color-neutral-200)); + border-bottom: solid 1px rgb(var(--sl-color-neutral-200)); border-left: none; border-right: none; } @@ -471,7 +438,7 @@ strong { .markdown-section p.tip, .markdown-section p.warn { position: relative; - background: var(--sl-color-gray-50); + background-color: rgb(var(--sl-color-neutral-50)); border-left: solid 4px transparent; border-radius: var(--sl-border-radius-medium); padding-left: 1.5rem; @@ -481,7 +448,7 @@ strong { .markdown-section p.warn:before { content: '!'; border-radius: 100%; - color: var(--sl-color-white); + color: rgb(var(--sl-color-neutral-0)); font-size: 14px; font-weight: bold; left: -12px; @@ -494,29 +461,29 @@ strong { } .markdown-section p.warn { - border-left-color: var(--sl-color-primary-500); + border-left-color: rgb(var(--sl-color-primary-600)); } .markdown-section p.warn:before { - background-color: var(--sl-color-primary-500); + background-color: rgb(var(--sl-color-primary-600)); } .markdown-section p.tip { - border-left-color: var(--sl-color-danger-500); + border-left-color: rgb(var(--sl-color-danger-600)); } .markdown-section p.tip:before { - background-color: var(--sl-color-danger-500); + background-color: rgb(var(--sl-color-danger-600)); } .markdown-section p.tip code, .markdown-section p.warn code { - background-color: var(--sl-color-gray-100); + background-color: rgb(var(--sl-color-neutral-100)); } /* Component headers */ .component-header { - border-bottom: solid 1px var(--sl-color-gray-200); + border-bottom: solid 1px rgb(var(--sl-color-neutral-200)); padding-bottom: 2rem; margin-top: -1rem; margin-bottom: 2rem; @@ -528,9 +495,9 @@ strong { margin: 0.75rem 0 0.25rem 0; } -.component-header__tag code { +.markdown-section .component-header__tag code { background: none; - color: var(--sl-color-gray-500); + color: rgb(var(--sl-color-neutral-600)); font-size: var(--sl-font-size-large); padding: 0; margin: 0; @@ -546,71 +513,122 @@ strong { line-height: 1.6; } -/* Copy button */ -.docsify-copy-code-button { - font-size: var(--sl-font-size-small) !important; - border-top-right-radius: var(--sl-border-radius-medium) !important; - border-bottom-left-radius: var(--sl-border-radius-medium) !important; -} - /* Repo buttons */ -html .repo-button { - display: inline-flex; - align-items: center; - background-color: var(--sl-color-white); - border: solid 1px var(--sl-color-gray-200); - border-radius: var(--sl-border-radius-medium); - box-shadow: var(--sl-shadow-x-small); - font-size: var(--sl-font-size-small); - font-weight: var(--sl-font-weight-semibold); - line-height: 2; - text-decoration: none; - color: var(--sl-color-gray-700); - padding: var(--sl-spacing-xx-small) var(--sl-spacing-small); - margin-bottom: var(--sl-spacing-xx-small); - transition: 0.25s all; +.repo-button--sponsor sl-icon { + color: rgb(var(--sl-color-pink-600)); } -html .repo-button:hover { - text-decoration: none; - background-color: var(--sl-color-gray-50); - border: solid 1px var(--sl-color-gray-200); +.repo-button--github sl-icon { + color: rgb(var(--sl-color-neutral-700)); } -html .repo-button:focus { - outline: none; - border-color: var(--sl-color-primary-500); - box-shadow: 0 0 0 var(--sl-focus-ring-width) var(--sl-focus-ring-color-primary); +.repo-button--twitter sl-icon { + color: rgb(var(--sl-color-sky-500)); } -html .repo-button:not(:last-of-type) { - margin-right: 0.125rem; +@media screen and (max-width: 400px) { + :not(.sidebar-buttons) > .repo-button { + width: 100%; + margin-bottom: 1rem; + } } -html .repo-button sl-icon { - position: relative; - vertical-align: middle; - margin-right: 0.35rem; -} - -html .repo-button--small { - font-size: var(--sl-font-size-x-small); - padding: var(--sl-spacing-xxx-small) var(--sl-spacing-x-small); -} - -html .repo-button--sponsor sl-icon { - color: #ea4aaa; -} - -html .repo-button--github sl-icon { - color: #242a2e; -} - -html .repo-button--twitter sl-icon { - color: #1ea0f2; -} - -body[data-page^='tokens/'] .table-wrapper td:first-child, -body[data-page^='tokens/'] .table-wrapper td:first-child code { +body[data-page^='/tokens/'] .table-wrapper td:first-child, +body[data-page^='/tokens/'] .table-wrapper td:first-child code { white-space: nowrap; } + +/* Border radius demo */ +.border-radius-demo { + width: 3rem; + height: 3rem; + background: rgb(var(--sl-color-primary-600)); +} + +/* Transition demo */ +.transition-demo { + position: relative; + background: rgb(var(--sl-color-neutral-200)); + width: 8rem; + height: 2rem; +} + +.transition-demo:after { + content: ''; + position: absolute; + background-color: rgb(var(--sl-color-primary-600)); + top: 0; + left: 0; + width: 0; + height: 100%; + transition-duration: inherit; + transition-property: width; +} + +.transition-demo:hover:after { + width: 100%; +} + +/* Spacing demo */ +.spacing-demo { + width: 100px; + background: rgb(var(--sl-color-primary-600)); +} + +/* Elevation dmeo */ +.elevation-demo { + background: transparent; + border-radius: 3px; + width: 4rem; + height: 4rem; + margin: 1rem; +} + +/* Color palettes */ +.color-palette { + display: grid; + grid-template-columns: 200px repeat(11, 1fr); + gap: 1rem var(--sl-spacing-2x-small); + margin: 2rem 0; +} + +.color-palette__name { + font-size: var(--sl-font-size-medium); + font-weight: var(--sl-font-weight-semibold); + grid-template-columns: repeat(11, 1fr); +} + +.color-palette__name code { + background: none; + font-size: var(--sl-font-size-x-small); +} + +.color-palette__example { + font-size: var(--sl-font-size-x-small); + text-align: center; +} + +.color-palette__swatch { + height: 3rem; + border-radius: var(--sl-border-radius-small); +} + +.color-palette__swatch--border { + box-shadow: inset 0 0 0 1px rgb(var(--sl-color-neutral-1000) / 10%); +} + +@media screen and (max-width: 1200px) { + .color-palette { + grid-template-columns: repeat(6, 1fr); + } + + .color-palette__name { + grid-column-start: span 6; + } +} + +.not-found-image { + display: block; + max-width: 460px; + margin: 2rem 0; +} diff --git a/docs/components/alert.md b/docs/components/alert.md index c113e9bd9..b8d8fb8ba 100644 --- a/docs/components/alert.md +++ b/docs/components/alert.md @@ -36,7 +36,7 @@ Set the `type` attribute to change the alert's type.
    - + Your settings have been updated
    Settings will take affect on next login. @@ -126,7 +126,7 @@ You should always use the `closable` attribute so users can dismiss the notifica
    Primary Success - Info + Neutral Warning Danger @@ -142,7 +142,7 @@ You should always use the `closable` attribute so users can dismiss the notifica You can safely exit the app now. - + Your settings have been updated
    Settings will take affect on next login. @@ -164,7 +164,7 @@ You should always use the `closable` attribute so users can dismiss the notifica
    - - - - - - + + + + + +
    @@ -558,7 +558,7 @@ If you want to change the icons Shoelace uses internally, you can register an ic +
    +``` + +?> When you create a mutation observer, you must indicate what changes it should respond to by including at least one of `attr`, `child-list`, or `char-data`. If you don't specify at least one of these attributes, no mutation events will be emitted. + +## Examples + +### Child List + +Use the `child-list` attribute to watch for new child elements that are added or removed. + +```html preview +
    + +
    + Add button +
    +
    + + 👆 Add and remove buttons and watch the console + + + + +
    +``` + +[component-metadata:sl-mutation-observer] diff --git a/docs/components/progress-bar.md b/docs/components/progress-bar.md index cff5327f4..9818b132e 100644 --- a/docs/components/progress-bar.md +++ b/docs/components/progress-bar.md @@ -5,7 +5,7 @@ Progress bars are used to show the status of an ongoing operation. ```html preview - + ``` ## Examples @@ -15,7 +15,7 @@ Progress bars are used to show the status of an ongoing operation. Use the `--height` custom property to set the progress bar's height. ```html preview - + ``` ### Labels @@ -23,7 +23,7 @@ Use the `--height` custom property to set the progress bar's height. Use the default slot to show a label. ```html preview -50% +50%
    @@ -36,22 +36,22 @@ Use the default slot to show a label. const addButton = subtractButton.nextElementSibling; addButton.addEventListener('click', () => { - const percentage = Math.min(100, progressBar.percentage + 10); - progressBar.percentage = percentage; - progressBar.textContent = `${percentage}%`; + const value = Math.min(100, progressBar.value + 10); + progressBar.value = value; + progressBar.textContent = `${value}%`; }); subtractButton.addEventListener('click', () => { - const percentage = Math.max(0, progressBar.percentage - 10) - progressBar.percentage = percentage; - progressBar.textContent = `${percentage}%`; + const value = Math.max(0, progressBar.value - 10) + progressBar.value = value; + progressBar.textContent = `${value}%`; }); ``` ### Indeterminate -The `indeterminate` attribute can be used to inform the user that the operation is pending, but its status cannot currently be determined. In this state, `percentage` is ignored and the label, if present, will not be shown. +The `indeterminate` attribute can be used to inform the user that the operation is pending, but its status cannot currently be determined. In this state, `value` is ignored and the label, if present, will not be shown. ```html preview diff --git a/docs/components/progress-ring.md b/docs/components/progress-ring.md index 04c83f9c1..ba1c1a8c4 100644 --- a/docs/components/progress-ring.md +++ b/docs/components/progress-ring.md @@ -5,25 +5,25 @@ Progress rings are used to show the progress of a determinate operation in a circular fashion. ```html preview - + ``` ## Examples ### Size -Use the `size` attribute to set the diameter of the progress ring. +Use the `--size` custom property to set the diameter of the progress ring. ```html preview - + ``` -### Stroke Width +### Track Width -Use the `stroke-width` attribute to set the width of the progress ring's indicator. +Use the `track-width` attribute to set the width of the progress ring's track. ```html preview - + ``` ### Colors @@ -32,8 +32,11 @@ To change the color, use the `--track-color` and `--indicator-color` custom prop ```html preview ``` @@ -42,7 +45,7 @@ To change the color, use the `--track-color` and `--indicator-color` custom prop Use the default slot to show a label. ```html preview -50% +50%
    @@ -55,15 +58,15 @@ Use the default slot to show a label. const addButton = subtractButton.nextElementSibling; addButton.addEventListener('click', () => { - const percentage = Math.min(100, progressRing.percentage + 10); - progressRing.percentage = percentage; - progressRing.textContent = `${percentage}%`; + const value = Math.min(100, progressRing.value + 10); + progressRing.value = value; + progressRing.textContent = `${value}%`; }); subtractButton.addEventListener('click', () => { - const percentage = Math.max(0, progressRing.percentage - 10) - progressRing.percentage = percentage; - progressRing.textContent = `${percentage}%`; + const value = Math.max(0, progressRing.value - 10) + progressRing.value = value; + progressRing.textContent = `${value}%`; }); ``` diff --git a/docs/components/radio-group.md b/docs/components/radio-group.md index 71a528b74..e4d5168eb 100644 --- a/docs/components/radio-group.md +++ b/docs/components/radio-group.md @@ -14,12 +14,12 @@ Radio Groups are used to group multiple radios so they function as a single cont ## Examples -### Hiding the Fieldset +### Showing the Fieldset -You can hide the fieldset and legend that wraps the radio group using the `no-fieldset` attribute. In this case, a label is still required for assistive devices to properly identify the control. +You can show a fieldset and legend that wraps the radio group using the `fieldset` attribute. ```html preview - + Item 1 Item 2 Item 3 diff --git a/docs/components/range.md b/docs/components/range.md index 963bcbf42..9d4f27fcd 100644 --- a/docs/components/range.md +++ b/docs/components/range.md @@ -5,7 +5,7 @@ Ranges allow the user to select a single value within a given range using a slider. ```html preview - + ``` ?> This component doesn't work with standard forms. Use [``](/components/form) instead. @@ -36,6 +36,17 @@ To disable the tooltip, set `tooltip` to `none`. ``` +### Custom Track Colors + +You can customize the active and inactive portions of the track using the `--track-color-active` and `--track-color-inactive` custom properties. + +```html preview + +``` + ### Custom Tooltip Formatter You can change the tooltip's content by setting the `tooltipFormatter` property to a function that accepts the range's value as an argument. diff --git a/docs/components/rating.md b/docs/components/rating.md index c848d244d..6851f8852 100644 --- a/docs/components/rating.md +++ b/docs/components/rating.md @@ -69,9 +69,9 @@ Use the `disable` attribute to disable the rating. ``` diff --git a/docs/components/resize-observer.md b/docs/components/resize-observer.md index 98db040d1..9dbd6e905 100644 --- a/docs/components/resize-observer.md +++ b/docs/components/resize-observer.md @@ -2,9 +2,9 @@ [component-header:sl-resize-observer] -Resize observers offer a thin, declarative interface to the [`ResizeObserver API`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver). +The Resize Observer component offers a thin, declarative interface to the [`ResizeObserver API`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver). -The resize observer will report changes to the dimensions of the elements it wraps through the `sl-resize` event. When emitted, a collection of [`ResizeObserverEntry`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserverEntry) objects will be attached to `event.detail`, containing the target element and information about its dimensions. +The resize observer will report changes to the dimensions of the elements it wraps through the `sl-resize` event. When emitted, a collection of [`ResizeObserverEntry`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserverEntry) objects will be attached to `event.detail` that contains the target element and information about its dimensions. ```html preview
    @@ -20,14 +20,14 @@ The resize observer will report changes to the dimensions of the elements it wra const resizeObserver = container.querySelector('sl-resize-observer'); resizeObserver.addEventListener('sl-resize', event => { - console.log(event); + console.log(event.detail); });