Compare commits

..

17 Commits

Author SHA1 Message Date
Cory LaViska
3217ce9f76 resolve feedback 2023-08-21 10:56:25 -04:00
Cory LaViska
c6d69fdbd6 update changelog 2023-08-18 14:47:58 -04:00
Cory LaViska
77b40fa7b4 Merge branch 'next' into submenus 2023-08-18 14:43:17 -04:00
Cory LaViska
bebf74a1fb stay highlighted when submenu is open 2023-08-18 14:40:21 -04:00
Cory LaViska
f524d20216 polish up submenu stuff 2023-08-18 14:18:38 -04:00
Cory LaViska
021c32ab32 Merge branch 'next-eycrb' of github.com:ecyrb/shoelace-ecyrb-fork into ecyrb-next-eycrb 2023-08-18 13:04:14 -04:00
Bryce Moore
dbf506d78f Submenu tweaks ...
- 100 ms delay when opening submenus on mouseover
- Shadows added
- Distance added to popup to have submenus overlap menu slightly.
2023-07-14 15:13:07 -04:00
Bryce Moore
1d826a9c53 fix: Prevent menu's extraneous Enter / space key propagation.
Menu's handleKeyDown calls item.click (to emit the selection).
Propagating the keyboard event on Enter / space would the cause re-entry
into a submenu, so prevent the needless propagation.
2023-07-13 09:55:45 -04:00
Bryce Moore
58d6cad39a fix: 2 changes to menu / submenu on-click behavior:
1. Close submenu on click explicitly, so this occurs even if the menu is
   not inside of an sl-dropdown.

2. In menu, ignore clicks that do not explicitly target a menu-item.
   Clicks that were on (e.g. a menu-border) were emitting select events.
2023-07-13 08:49:10 -04:00
Bryce Moore
e0e96c8a0a style: Eslint warnings and errors fixed. npm run verify now passes. 2023-07-13 06:26:44 -04:00
Bryce Moore
25a146ffd1 Cleanup: Removed dead code and dead code comments. 2023-07-11 02:50:48 -04:00
Bryce Moore
c55ba0467e Merge branch 'next' into next-eycrb 2023-07-08 08:16:46 -04:00
Bryce Moore
126b0e34bd [WIP] Submenu WIP continues.
- Submenus now close on change-of-focus, not a timeout.
- Keyboard navigation support added.
- Skidding fix for better alignment.
- Submenu documentation moved to Menu page.
- Tests for accessibility, right and left arrow keys.
2023-07-07 09:43:40 -04:00
Bryce Moore
7aca8d7300 Revert "PoC working of ArrowRight to focus on submenu."
(Didn't mean to publish this.)

This reverts commit be04e9a221.
2023-06-30 09:52:54 -04:00
Bryce Moore
be04e9a221 PoC working of ArrowRight to focus on submenu. 2023-06-30 07:44:55 -04:00
Bryce
354404484e Update submenu-controller.ts
Removed extraneous `console.log()`.
2023-06-28 02:43:51 -04:00
Bryce Moore
b48d072bc8 [RFC] Proof-of-concept commit for submenu support
This is a Request For Comments to seek directional guidance towards
implementing the submenu slot of menu-item.

Includes:
- SubmenuController to manage event listeners on menu-item.
- Example usage in menu-item documentation.
- Trivial tests to check rendering.

Outstanding questions include:
- Accessibility concerns. E.g. where to handle 'ArrowRight',
  'ArrowLeft'?
- Should selection of menu-item denoting submenu be possible or
  customizable?
- How to parameterize contained popup?
- Implementation concerns:
  - Use of ref / id
  - delegation of some rendering to the controller
  - What to test

Related to [#620](https://github.com/shoelace-style/shoelace/issues/620).
2023-06-28 01:08:37 -04:00
9 changed files with 111 additions and 51 deletions

View File

@@ -1,5 +1,3 @@
let codeBlockId = 0;
/**
* Adds copy code buttons to code fields. The provided doc should be a document object provided by JSDOM. The same
* document will be returned with the appropriate DOM manipulations.
@@ -7,14 +5,19 @@ let codeBlockId = 0;
module.exports = function (doc) {
doc.querySelectorAll('pre > code').forEach(code => {
const pre = code.closest('pre');
const button = doc.createElement('sl-copy-button');
if (!code.id) {
code.id = `code-block-${++codeBlockId}`;
}
const button = doc.createElement('button');
button.setAttribute('type', 'button');
button.classList.add('copy-code-button');
button.setAttribute('from', code.id);
button.setAttribute('aria-label', 'Copy');
button.innerHTML = `
<svg class="copy-code-button__copy-icon" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-files" viewBox="0 0 16 16" part="svg">
<path d="M13 0H6a2 2 0 0 0-2 2 2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h7a2 2 0 0 0 2-2 2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm0 13V4a2 2 0 0 0-2-2H5a1 1 0 0 1 1-1h7a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1zM3 4a1 1 0 0 1 1-1h7a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V4z"></path>
</svg>
<svg class="copy-code-button__copied-icon" style="display: none;" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-check-lg" viewBox="0 0 16 16" part="svg">
<path d="M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425a.247.247 0 0 1 .02-.022Z"></path>
</svg>
`;
pre.append(button);
});

View File

@@ -163,6 +163,32 @@
});
})();
//
// Copy code buttons
//
(() => {
document.addEventListener('click', event => {
const button = event.target.closest('.copy-code-button');
const pre = button?.closest('pre');
const code = pre?.querySelector('code');
const copyIcon = button?.querySelector('.copy-code-button__copy-icon');
const copiedIcon = button?.querySelector('.copy-code-button__copied-icon');
if (button && code) {
navigator.clipboard.writeText(code.innerText);
copyIcon.style.display = 'none';
copiedIcon.style.display = 'inline';
button.classList.add('copy-code-button--copied');
setTimeout(() => {
copyIcon.style.display = 'inline';
copiedIcon.style.display = 'none';
button.classList.remove('copy-code-button--copied');
}, 1000);
}
});
})();
//
// Smooth links
//

View File

@@ -506,31 +506,31 @@ pre .token.italic {
/* Copy code button */
.copy-code-button {
display: flex;
align-items: center;
justify-content: center;
position: absolute;
top: 0;
right: 0;
white-space: normal;
top: 0.5rem;
right: 0.5rem;
background: var(--sl-color-neutral-0);
border-radius: calc(var(--docs-border-radius) * 0.875);
border: solid 1px var(--sl-color-neutral-200);
color: var(--sl-color-neutral-800);
transition: 150ms opacity, 150ms scale;
text-transform: uppercase;
padding: 0.5rem;
margin: 0;
cursor: pointer;
transition: 100ms opacity, 100ms scale;
}
.copy-code-button::part(button) {
background-color: var(--sl-color-neutral-50);
border-radius: 0 var(--docs-border-radius) 0 var(--docs-border-radius);
padding: 0.75rem;
}
.copy-code-button::part(button):hover {
background-color: color-mix(in oklch, var(--sl-color-neutral-50), var(--sl-color-neutral-1000) 3%);
}
.copy-code-button::part(button):active {
background-color: color-mix(in oklch, var(--sl-color-neutral-50), var(--sl-color-neutral-1000) 6%);
.copy-code-button svg {
width: 1rem;
height: 1rem;
}
pre .copy-code-button {
opacity: 0;
scale: 0.75;
scale: 0.9;
}
pre:hover .copy-code-button,
@@ -539,6 +539,13 @@ pre:hover .copy-code-button,
scale: 1;
}
pre:hover .copy-code-button:hover,
pre:hover .copy-code-button--copied {
background: var(--sl-color-neutral-200);
border-color: var(--sl-color-neutral-300);
color: var(--sl-color-neutral-900);
}
/* Callouts */
.callout {
position: relative;

View File

@@ -20,8 +20,6 @@ New versions of Shoelace are released as-needed and generally occur when a criti
- Fixed a regression that caused `<sl-radio-button>` to render incorrectly with gaps [#1523]
- Improved expand/collapse behavior of `<sl-tree>` to work more like users expect [#1521]
- Improved `<sl-menu-item>` so labels truncate properly instead of getting chopped and overflowing
- Removed the extra `React.Component` around `@lit-labs/react` wrapper. [#1531]
- Upgrade `@lit-labs/react` to v2.0.1. [#1531]
## 2.7.0

38
package-lock.json generated
View File

@@ -11,7 +11,7 @@
"dependencies": {
"@ctrl/tinycolor": "^3.5.0",
"@floating-ui/dom": "^1.2.1",
"@lit-labs/react": "^2.0.1",
"@lit-labs/react": "^1.2.1",
"@shoelace-style/animations": "^1.1.0",
"@shoelace-style/localize": "^3.1.1",
"composed-offset-position": "^0.0.4",
@@ -1474,12 +1474,9 @@
}
},
"node_modules/@lit-labs/react": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@lit-labs/react/-/react-2.0.1.tgz",
"integrity": "sha512-Nj+XB3HamqaWefN91lpFPJaqjJ78XzGkPWCedB4jyH22GBFEenpE9A/h8B/2dnIGXtNtd9D/RFpUdQ/dBtWFqA==",
"peerDependencies": {
"@types/react": "17 || 18"
}
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@lit-labs/react/-/react-1.2.1.tgz",
"integrity": "sha512-DiZdJYFU0tBbdQkfwwRSwYyI/mcWkg3sWesKRsHUd4G+NekTmmeq9fzsurvcKTNVa0comNljwtg4Hvi1ds3V+A=="
},
"node_modules/@lit-labs/ssr-dom-shim": {
"version": "1.1.1",
@@ -2273,7 +2270,8 @@
"node_modules/@types/prop-types": {
"version": "15.7.4",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz",
"integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ=="
"integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==",
"dev": true
},
"node_modules/@types/qs": {
"version": "6.9.7",
@@ -2291,6 +2289,7 @@
"version": "18.0.26",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.26.tgz",
"integrity": "sha512-hCR3PJQsAIXyxhTNSiDFY//LhnMZWpNNr5etoCqx/iUfGc5gXWtQR2Phl908jVR6uPXacojQWTg4qRpkxTuGug==",
"dev": true,
"dependencies": {
"@types/prop-types": "*",
"@types/scheduler": "*",
@@ -2318,7 +2317,8 @@
"node_modules/@types/scheduler": {
"version": "0.16.2",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
"integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="
"integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==",
"dev": true
},
"node_modules/@types/semver": {
"version": "7.5.0",
@@ -5685,7 +5685,8 @@
"node_modules/csstype": {
"version": "3.0.10",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.10.tgz",
"integrity": "sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA=="
"integrity": "sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA==",
"dev": true
},
"node_modules/custom-element-jet-brains-integration": {
"version": "1.1.0",
@@ -18290,10 +18291,9 @@
}
},
"@lit-labs/react": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@lit-labs/react/-/react-2.0.1.tgz",
"integrity": "sha512-Nj+XB3HamqaWefN91lpFPJaqjJ78XzGkPWCedB4jyH22GBFEenpE9A/h8B/2dnIGXtNtd9D/RFpUdQ/dBtWFqA==",
"requires": {}
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@lit-labs/react/-/react-1.2.1.tgz",
"integrity": "sha512-DiZdJYFU0tBbdQkfwwRSwYyI/mcWkg3sWesKRsHUd4G+NekTmmeq9fzsurvcKTNVa0comNljwtg4Hvi1ds3V+A=="
},
"@lit-labs/ssr-dom-shim": {
"version": "1.1.1",
@@ -18998,7 +18998,8 @@
"@types/prop-types": {
"version": "15.7.4",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz",
"integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ=="
"integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==",
"dev": true
},
"@types/qs": {
"version": "6.9.7",
@@ -19016,6 +19017,7 @@
"version": "18.0.26",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.26.tgz",
"integrity": "sha512-hCR3PJQsAIXyxhTNSiDFY//LhnMZWpNNr5etoCqx/iUfGc5gXWtQR2Phl908jVR6uPXacojQWTg4qRpkxTuGug==",
"dev": true,
"requires": {
"@types/prop-types": "*",
"@types/scheduler": "*",
@@ -19043,7 +19045,8 @@
"@types/scheduler": {
"version": "0.16.2",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
"integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="
"integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==",
"dev": true
},
"@types/semver": {
"version": "7.5.0",
@@ -21511,7 +21514,8 @@
"csstype": {
"version": "3.0.10",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.10.tgz",
"integrity": "sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA=="
"integrity": "sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA==",
"dev": true
},
"custom-element-jet-brains-integration": {
"version": "1.1.0",

View File

@@ -62,7 +62,7 @@
"dependencies": {
"@ctrl/tinycolor": "^3.5.0",
"@floating-ui/dom": "^1.2.1",
"@lit-labs/react": "^2.0.1",
"@lit-labs/react": "^1.2.1",
"@shoelace-style/animations": "^1.1.0",
"@shoelace-style/localize": "^3.1.1",
"composed-offset-position": "^0.0.4",

View File

@@ -51,11 +51,18 @@ components.map(component => {
${eventImports}
${eventExports}
const tagName = '${component.tagName}'
Component.define('${component.tagName}')
export type ForwardComponent<
Element extends HTMLElement,
ReactComponent extends React.ElementType
> = React.JSXElementConstructor<
React.ComponentPropsWithoutRef<ReactComponent> & {
ref?: React.ForwardedRef<Element>;
}
> & { displayName?: string }
${jsDoc}
const reactWrapper = createComponent({
const tagName = '${component.tagName}'
const component = createComponent({
tagName,
elementClass: Component,
react: React,
@@ -65,7 +72,20 @@ components.map(component => {
displayName: "${component.name}"
})
export default reactWrapper
${jsDoc}
class SlComponent extends React.Component<Parameters<typeof component>[0]> {
constructor (...args: Parameters<typeof component>) {
super(...args)
Component.define(tagName)
}
render () {
const { children, ...props } = this.props
return React.createElement(component, props, children)
}
}
export default SlComponent as ForwardComponent<Component, typeof SlComponent>;
`,
Object.assign(prettierConfig, {
parser: 'babel-ts'

View File

@@ -28,6 +28,7 @@
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"useUnknownInCatchVariables": true,
"baseUrl": ".",
"types": [
"mocha",
"user-agent-data-types"

View File

@@ -1,6 +1,7 @@
{
"extends": "./tsconfig",
"compilerOptions": {
"baseUrl": ".",
"rootDir": "./src"
},
"include": ["src"],