Compare commits

..

2 Commits

Author SHA1 Message Date
Cory LaViska
e58d95e7ac Merge branch 'next' into hints 2025-07-17 11:55:45 -04:00
Cory LaViska
c8f01782af add back id="hint" 2025-07-16 16:52:06 -04:00
38 changed files with 36 additions and 206 deletions

21
package-lock.json generated
View File

@@ -13988,6 +13988,7 @@
"qr-creator": "^1.0.0",
"style-observer": "^0.0.7"
},
"devDependencies": {},
"engines": {
"node": ">=14.17.0"
}
@@ -14003,32 +14004,14 @@
"@shoelace-style/localize": "^3.2.1",
"composed-offset-position": "^0.0.6",
"lit": "^3.2.1",
"nanoid": "^5.1.5",
"qr-creator": "^1.0.0",
"style-observer": "^0.0.7"
},
"devDependencies": {},
"engines": {
"node": ">=14.17.0"
}
},
"packages/webawesome-pro/node_modules/nanoid": {
"version": "5.1.5",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.5.tgz",
"integrity": "sha512-Ir/+ZpE9fDsNH0hQ3C68uyThDXzYcim2EqcZ8zn8Chtt1iylPT9xXJB0kPCnqzgcEGikO9RxSrh63MsmVCU7Fw==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"bin": {
"nanoid": "bin/nanoid.js"
},
"engines": {
"node": "^18 || >=20"
}
},
"packages/webawesome/node_modules/nanoid": {
"version": "5.1.5",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.5.tgz",

View File

@@ -261,10 +261,13 @@ export default async function (eleventyConfig) {
// });
// }
// For a server build, we expect a server to run the second transform.
// For dev builds, we run the second transform in a middleware.
if (!isDev && !serverBuild) {
if (!isDev) {
eleventyConfig.addTransform('simulate-webawesome-app', function (content) {
// For a server build, we expect a server to run the second transform.
if (serverBuild) {
return content;
}
// Only run the transform on files nunjucks would transform.
if (!this.page.inputPath.match(/.(md|html|njk)$/)) {
return content;

View File

@@ -46,18 +46,6 @@ Font Awesome users can set their kit code to unlock Font Awesome Pro icons. You
---
{# This looks weird, but without it, markdownItAttrs flags the raw calls incorrectly. #}
<div>
{%- raw -%}
{% if currentUser.hasPro %}
<div>
{% include "server/pro-setup.njk" ignore missing %}
</div>
{% endif %}
{% endraw %}
</div>
## Advanced Setup
The autoloader is the easiest way to use Web Awesome, but different projects (or your own preferences!) may require different installation methods.

View File

@@ -26,7 +26,6 @@ Components with the <wa-badge variant="warning">Experimental</wa-badge> badge sh
- Fixed a bug in `<wa-card>` that caused slotted media to have incorrectly rounded corners [issue:1107]
- Fixed a bug in `<wa-button-group>` that prevented pill buttons from rendering corners properly [issue:1165]
- Fixed a bug in `<wa-button-group>` that caused some vertical groups to appear horizontal [issue:1152]
- Improved accessibility of `<wa-animated-image>` so keyboard users can focus and toggle the animation [issue:1177]
## 3.0.0-beta.2

View File

@@ -380,19 +380,6 @@ Add the `wa-pill` class to give buttons rounded edges.
<button class="wa-pill">Pill button</button>
```
When using `<wa-icon>` within a button, wrap adjacent label text in `<span>` or similar to automatically add margin between the icon and the label, just like the `start` and `end` slots of `<wa-button>`.
```html {.example}
<button>
<wa-icon name="plane-departure"></wa-icon>
<span>Start Icon</span>
</button>
<button>
<span>End Icon</span>
<wa-icon name="plane-arrival"></wa-icon>
</button>
```
### Form controls
Create a variety of form controls with `<input type="">`, `<select>`, and `<textarea>`. Each control closely matches the appearance of the corresponding Web Awesome component.

View File

@@ -34,8 +34,7 @@ const isDeveloping = process.argv.includes('--develop');
* @typedef {Object} BuildOptions
* @property {Array<string>} [watchedSrcDirectories]
* @property {Array<string>} [watchedDocsDirectories]
* @property {(eventName: "change" | "add" | "unlink", filePath: string) => unknown} [beforeWatchEvent]
* @property {(eventName: "change" | "add" | "unlink", filePath: string) => unknown} [afterWatchEvent]
* @property {(eventName: "change" | "add" | "unlink", filePath: string) => unknown} [onWatchEvent]
*/
/**
@@ -50,6 +49,8 @@ export async function build(options = {}) {
options.watchedDocsDirectories = [getDocsDir()];
}
function measureStep() {}
/**
* Runs the full build.
*/
@@ -121,11 +122,6 @@ export async function build(options = {}) {
* Generates React wrappers for all components.
*/
function generateReactWrappers() {
// Used by webawesome-app to make re-rendering not miserable with extra React file generation.
if (process.env.SKIP_SLOW_STEPS === 'true') {
return Promise.resolve();
}
spinner.start('Generating React wrappers');
try {
@@ -160,11 +156,6 @@ export async function build(options = {}) {
* Runs TypeScript to generate types.
*/
async function generateTypes() {
// Used by webawesome-app to make re-rendering not miserable with extra TS compilations.
if (process.env.SKIP_SLOW_STEPS === 'true') {
return Promise.resolve();
}
spinner.start('Running the TypeScript compiler');
const cwd = process.cwd();
@@ -386,25 +377,22 @@ export async function build(options = {}) {
},
);
const watchEvents = ['change', 'unlink', 'add'];
// TODO: Should probably listen for all of these instead of just "change"
const watchEvents = [
'change',
// "unlink",
// "add"
];
// Rebuild and reload when source files change
options.watchedSrcDirectories.forEach(dir => {
const watcher = bs.watch(join(dir, '**', '!(*.test).*'), { ignoreInitial: true });
const watcher = bs.watch(join(dir, '**', '!(*.test).*'));
watchEvents.forEach(evt => {
watcher.on(evt, handleWatchEvent(evt));
});
function handleWatchEvent(evt) {
return async filename => {
const changedFile = relative(getRootDir(), filename);
if (evt === 'changed') {
spinner.info(`File modified ${chalk.gray(`(${changedFile})`)}`);
} else if (evt === 'unlink') {
spinner.info(`File deleted ${chalk.gray(`(${changedFile})`)}`);
} else if (evt === 'add') {
spinner.info(`File added ${chalk.gray(`(${changedFile})`)}`);
}
spinner.info(`File modified ${chalk.gray(`(${relative(getRootDir(), filename)})`)}`);
try {
const isTestFile = filename.includes('.test.ts');
@@ -417,8 +405,8 @@ export async function build(options = {}) {
return;
}
if (typeof options.beforeWatchEvent === 'function') {
await options.beforeWatchEvent(evt, filename);
if (typeof options.onWatchEvent === 'function') {
await options.onWatchEvent(evt, filename);
}
// Copy stylesheets when CSS files change
@@ -438,10 +426,6 @@ export async function build(options = {}) {
// This needs to be outside of "isComponent" check because SSR needs to run on CSS files too.
await generateDocs({ spinner });
if (typeof options.afterWatchEvent === 'function') {
await options.afterWatchEvent(evt, filename);
}
reload();
} catch (err) {
console.error(chalk.red(err));
@@ -456,7 +440,7 @@ export async function build(options = {}) {
// Rebuild the docs and reload when the docs change
options.watchedDocsDirectories.forEach(dir => {
const watcher = bs.watch(join(dir, '**', '*.*'), { ignoreInitial: true });
const watcher = bs.watch(join(dir, '**', '*.*'));
watchEvents.forEach(evt => {
watcher.on(evt, handleWatchEvent(evt));
@@ -465,14 +449,10 @@ export async function build(options = {}) {
function handleWatchEvent(evt) {
return async filename => {
spinner.info(`File modified ${chalk.gray(`(${relative(getRootDir(), filename)})`)}`);
if (typeof options.beforeWatchEvent === 'function') {
await options.beforeWatchEvent(evt, filename);
if (typeof options.onWatchEvent === 'function') {
await options.onWatchEvent(evt, filename);
}
await generateDocs({ spinner });
if (typeof options.beforeWatchEvent === 'function') {
await options.afterWatchEvent(evt, filename);
}
reload();
};
}

View File

@@ -72,6 +72,7 @@ export async function generateDocs(options = {}) {
isDeveloping ??= process.argv.includes('--develop');
isIncremental ??= isDeveloping && !process.argv.includes('--no-incremental');
let eleventy = globalThis.eleventy;
/**
* Used by the webawesome-app to skip doc generation since it will do its own.
*/
@@ -79,8 +80,6 @@ export async function generateDocs(options = {}) {
return;
}
let eleventy = globalThis.eleventy;
spinner?.start?.('Writing the docs');
const outputs = {
@@ -119,7 +118,7 @@ export async function generateDocs(options = {}) {
return !line.includes('Watching');
});
const lastLine = info[info.length - 1];
output = chalk.gray(`(${info.join('')})`);
output = chalk.gray(`(${lastLine})`);
eleventy.logger.logger.reset();
}
} else {
@@ -138,23 +137,13 @@ export async function generateDocs(options = {}) {
if (!isDeveloping) {
await copy(getCdnDir(), join(getSiteDir(), 'dist'));
}
if (spinner) {
spinner.succeed(`Writing the docs ${output}`);
} else {
console.log(`Writing the docs ${output}`);
}
spinner?.succeed?.(`Writing the docs ${output}`);
} catch (error) {
console.warn = originalWarn;
console.error('\n\n' + chalk.red(error) + '\n');
if (spinner) {
spinner.fail(chalk.red(`Error while writing the docs.`));
} else {
console.error(chalk.red(`Error while writing the docs.`));
}
spinner?.fail?.(chalk.red(`Error while writing the docs.`));
if (!isDeveloping) {
process.exit(1);
}

View File

@@ -42,7 +42,7 @@ img[aria-hidden='true'] {
}
}
:where(:host([play]:not(:hover))) .control-box {
:host([play]:not(:hover)) .control-box {
opacity: 0;
}
@@ -50,16 +50,3 @@ img[aria-hidden='true'] {
:host(:not([play])) slot[name='pause-icon'] {
display: none;
}
/* Show control box on keyboard focus */
.animated-image {
&:focus {
outline: none;
}
&:focus-visible .control-box {
opacity: 1;
outline: var(--wa-focus-ring);
outline-offset: var(--wa-focus-ring-offset);
}
}

View File

@@ -4,7 +4,6 @@ import { WaErrorEvent } from '../../events/error.js';
import { WaLoadEvent } from '../../events/load.js';
import { watch } from '../../internal/watch.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import { LocalizeController } from '../../utilities/localize.js';
import '../icon/icon.js';
import styles from './animated-image.css';
@@ -31,8 +30,6 @@ import styles from './animated-image.css';
export default class WaAnimatedImage extends WebAwesomeElement {
static css = styles;
private readonly localize = new LocalizeController(this);
@query('.animated') animatedImage: HTMLImageElement;
@state() frozenFrame: string;
@@ -51,13 +48,6 @@ export default class WaAnimatedImage extends WebAwesomeElement {
this.play = !this.play;
}
private handleKeyDown(event: KeyboardEvent) {
if (event.key === 'Enter' || event.key === ' ') {
event.preventDefault();
this.play = !this.play;
}
}
private handleLoad() {
const canvas = document.createElement('canvas');
const { width, height } = this.animatedImage;
@@ -92,26 +82,15 @@ export default class WaAnimatedImage extends WebAwesomeElement {
}
render() {
const verb = this.localize.term(this.play ? 'pauseAnimation' : 'playAnimation');
const label = `${verb} ${this.alt}`;
return html`
<div
class="animated-image"
tabindex="0"
role="button"
aria-pressed=${this.play ? 'true' : 'false'}
aria-label=${label}
@click=${this.handleClick}
@keydown=${this.handleKeyDown}
>
<div class="animated-image">
<img
class="animated"
src=${this.src}
alt=${this.alt}
crossorigin="anonymous"
aria-hidden=${this.play ? 'false' : 'true'}
role="presentation"
@click=${this.handleClick}
@load=${this.handleLoad}
@error=${this.handleError}
/>
@@ -123,10 +102,10 @@ export default class WaAnimatedImage extends WebAwesomeElement {
src=${this.frozenFrame}
alt=${this.alt}
aria-hidden=${this.play ? 'true' : 'false'}
role="presentation"
@click=${this.handleClick}
/>
<div part="control-box" class="control-box" aria-hidden="true">
<div part="control-box" class="control-box">
<slot name="play-icon">
<wa-icon
name="play"

View File

@@ -564,6 +564,7 @@
display: inline-flex;
align-items: center;
justify-content: center;
gap: 0.5em;
height: var(--wa-form-control-height);
padding: 0 var(--wa-form-control-padding-inline);
@@ -708,16 +709,6 @@
&.wa-pill {
border-radius: var(--wa-border-radius-pill);
}
/* Adds space between icons and adjacent elements
* Prefer sibling selectors over :first-child/:last-child to avoid extra space when an icon is used alone */
& > wa-icon:has(+ *) {
margin-inline-end: 0.75em;
}
& > * + wa-icon {
margin-inline-start: 0.75em;
}
}
/* #endregion */

View File

@@ -24,8 +24,6 @@ const translation: Translation = {
if (num > 2 && num < 11) return `تم تحديد ${num} خيارات`;
return `تم تحديد ${num} خيار`;
},
pauseAnimation: 'إيقاف الرسوم المتحركة مؤقتًا',
playAnimation: 'تشغيل الرسوم المتحركة',
previousSlide: 'الشريحة السابقة',
progress: 'مقدار التقدم',
remove: 'حذف',

View File

@@ -22,8 +22,6 @@ const translation: Translation = {
if (num === 1) return 'Je vybrána jedna možnost';
return `Počet vybraných možností: ${num}`;
},
pauseAnimation: 'Pozastavit animaci',
playAnimation: 'Přehrát animaci',
previousSlide: 'Předchozí slide',
progress: 'Průběh',
remove: 'Odstranit',

View File

@@ -22,8 +22,6 @@ const translation: Translation = {
if (num === 1) return '1 valgt';
return `${num} valgt`;
},
pauseAnimation: 'Pause animation',
playAnimation: 'Afspil animation',
previousSlide: 'Forrige dias',
progress: 'Status',
remove: 'Fjern',

View File

@@ -22,8 +22,6 @@ const translation: Translation = {
if (num === 1) return '1 Option ausgewählt';
return `${num} Optionen ausgewählt`;
},
pauseAnimation: 'Animation pausieren',
playAnimation: 'Animation abspielen',
previousSlide: 'Vorherige Folie',
progress: 'Fortschritt',
remove: 'Entfernen',

View File

@@ -22,8 +22,6 @@ const translation: Translation = {
if (num === 1) return '1 option selected';
return `${num} options selected`;
},
pauseAnimation: 'Pause animation',
playAnimation: 'Play animation',
previousSlide: 'Previous slide',
progress: 'Progress',
remove: 'Remove',

View File

@@ -22,8 +22,6 @@ const translation: Translation = {
if (num === 1) return '1 opción seleccionada';
return `${num} opción seleccionada`;
},
pauseAnimation: 'Pausar animación',
playAnimation: 'Reproducir animación',
previousSlide: 'Diapositiva anterior',
progress: 'Progreso',
remove: 'Eliminar',

View File

@@ -22,8 +22,6 @@ const translation: Translation = {
if (num === 1) return '1 گزینه انتخاب شده است';
return `${num} گزینه انتخاب شده است`;
},
pauseAnimation: 'مکث انیمیشن',
playAnimation: 'پخش انیمیشن',
previousSlide: 'اسلاید قبلی',
progress: 'پیشرفت',
remove: 'حذف',

View File

@@ -22,8 +22,6 @@ const translation: Translation = {
if (num === 1) return 'Yksi vaihtoehto valittu';
return `${num} vaihtoehtoa valittu`;
},
pauseAnimation: 'Keskeytä animaatio',
playAnimation: 'Toista animaatio',
previousSlide: 'Edellinen dia',
progress: 'Edistyminen',
remove: 'Poista',

View File

@@ -22,8 +22,6 @@ const translation: Translation = {
if (num === 1) return '1 option sélectionnée';
return `${num} options sélectionnées`;
},
pauseAnimation: "Suspendre l'animation",
playAnimation: "Lire l'animation",
previousSlide: 'Diapositive précédente',
progress: 'Progrès',
remove: 'Retirer',

View File

@@ -16,15 +16,13 @@ const translation: Translation = {
goToSlide: (slide, count) => `עבור לשקופית ${slide} של ${count}`,
hidePassword: 'הסתר סיסמא',
loading: 'טוען',
nextSlide: 'השקף הבא',
nextSlide: 'Next slide',
numOptionsSelected: num => {
if (num === 0) return 'לא נבחרו אפשרויות';
if (num === 1) return 'נבחרה אפשרות אחת';
return `נבחרו ${num} אפשרויות`;
},
pauseAnimation: 'השהה אנימציה',
playAnimation: 'נגן אנימציה',
previousSlide: 'שקופית קודמת',
previousSlide: 'Previous slide',
progress: 'התקדמות',
remove: 'לְהַסִיר',
resize: 'שנה גודל',

View File

@@ -22,8 +22,6 @@ const translation: Translation = {
if (num === 1) return '1 opcija je odabrana';
return `${num} odabranih opcija`;
},
pauseAnimation: 'Pauziraj animaciju',
playAnimation: 'Reproduciraj animaciju',
previousSlide: 'Prethodni slajd',
progress: 'Napredak',
remove: 'Makni',

View File

@@ -22,8 +22,6 @@ const translation: Translation = {
if (num === 1) return '1 lehetőség kiválasztva';
return `${num} lehetőség kiválasztva`;
},
pauseAnimation: 'Animáció szüneteltetése',
playAnimation: 'Animáció lejátszása',
previousSlide: 'Előző dia',
progress: 'Folyamat',
remove: 'Eltávolítás',

View File

@@ -22,8 +22,6 @@ const translation: Translation = {
if (num === 1) return '1 opsi yang dipilih';
return `${num} opsi yang dipilih`;
},
pauseAnimation: 'Jeda animasi',
playAnimation: 'Putar animasi',
previousSlide: 'Slide sebelumnya',
progress: 'Kemajuan',
remove: 'Hapus',

View File

@@ -22,8 +22,6 @@ const translation: Translation = {
if (num === 1) return '1 opzione selezionata';
return `${num} opzioni selezionate`;
},
pauseAnimation: 'Metti in pausa animazione',
playAnimation: 'Riproduci animazione',
previousSlide: 'Diapositiva precedente',
progress: 'Avanzamento',
remove: 'Rimuovi',

View File

@@ -21,8 +21,6 @@ const translation: Translation = {
if (num === 0) return '項目が選択されていません';
return `${num} 個の項目が選択されました`;
},
pauseAnimation: 'アニメーションを一時停止',
playAnimation: 'アニメーションを再生',
previousSlide: '前のスライド',
progress: '進行',
remove: '削除',

View File

@@ -22,8 +22,6 @@ const translation: Translation = {
if (num === 1) return 'Ett alternativ valgt';
return `${num} alternativer valgt`;
},
pauseAnimation: 'Sett animasjon på pause',
playAnimation: 'Spill av animasjon',
previousSlide: 'Forrige visning',
progress: 'Fremdrift',
remove: 'Fjern',

View File

@@ -22,8 +22,6 @@ const translation: Translation = {
if (num === 1) return '1 optie geselecteerd';
return `${num} opties geselecteerd`;
},
pauseAnimation: 'Animatie pauzeren',
playAnimation: 'Animatie afspelen',
previousSlide: 'Vorige dia',
progress: 'Voortgang',
remove: 'Verwijderen',

View File

@@ -22,8 +22,6 @@ const translation: Translation = {
if (num === 1) return 'Eitt alternativ valt';
return `${num} alternativ valt`;
},
pauseAnimation: 'Set animasjon på pause',
playAnimation: 'Spel av animasjon',
previousSlide: 'Førre visning',
progress: 'Framdrift',
remove: 'Fjern',

View File

@@ -22,8 +22,6 @@ const translation: Translation = {
if (num === 1) return 'Wybrano 1 opcję';
return `Wybrano ${num} opcje`;
},
pauseAnimation: 'Wstrzymaj animację',
playAnimation: 'Odtwórz animację',
previousSlide: 'Poprzedni slajd',
progress: 'Postęp',
remove: 'Usunąć',

View File

@@ -22,8 +22,6 @@ const translation: Translation = {
if (num === 1) return '1 opção selecionada';
return `${num} opções selecionadas`;
},
pauseAnimation: 'Pausar animação',
playAnimation: 'Reproduzir animação',
previousSlide: 'Slide anterior',
progress: 'Progresso',
remove: 'Remover',

View File

@@ -22,8 +22,6 @@ const translation: Translation = {
if (num === 1) return 'Выбран 1 вариант';
return `выбрано ${num} варианта`;
},
pauseAnimation: 'Приостановить анимацию',
playAnimation: 'Воспроизвести анимацию',
previousSlide: 'Предыдущий слайд',
progress: 'Прогресс',
remove: 'Удалить',

View File

@@ -24,8 +24,6 @@ const translation: Translation = {
if (num === 3 || num === 4) return `${num} možnosti izbrane`;
return `${num} možnosti izbranih`;
},
pauseAnimation: 'Zaustavi animacijo',
playAnimation: 'Predvajaj animacijo',
previousSlide: 'Prejšnji diapozitiv',
progress: 'Napredek',
remove: 'Odstrani',

View File

@@ -22,8 +22,6 @@ const translation: Translation = {
if (num === 1) return '1 alternativ valt';
return `${num} alternativ valda`;
},
pauseAnimation: 'Pausa animation',
playAnimation: 'Spela upp animation',
previousSlide: 'Föregående bild',
progress: 'Framsteg',
remove: 'Ta bort',

View File

@@ -22,8 +22,6 @@ const translation: Translation = {
if (num === 1) return '1 seçenek seçildi';
return `${num} seçenek seçildi`;
},
pauseAnimation: 'Animasyonu duraklat',
playAnimation: 'Animasyonu oynat',
previousSlide: 'Bir onceki slayt',
progress: 'İlerleme',
remove: 'Kaldır',

View File

@@ -24,8 +24,6 @@ const translation: Translation = {
if (n === 2 || n === 3 || n === 4) return `вибрано ${num} варіанти`;
return `вибрано ${num} варіантів`;
},
pauseAnimation: 'Призупинити анімацію',
playAnimation: 'Відтворити анімацію',
previousSlide: 'Попередній слайд',
progress: 'Поступ',
remove: 'Видалити',

View File

@@ -22,8 +22,6 @@ const translation: Translation = {
if (num === 1) return '已选择 1 个项目';
return `${num} 选择项目`;
},
pauseAnimation: '暂停动画',
playAnimation: '播放动画',
previousSlide: '上一张幻灯片',
progress: '进度',
remove: '删除',

View File

@@ -22,8 +22,6 @@ const translation: Translation = {
if (num === 1) return '已選擇 1 個項目';
return `${num} 選擇項目`;
},
pauseAnimation: '暫停動畫',
playAnimation: '播放動畫',
previousSlide: '上一張幻燈片',
progress: '進度',
remove: '移除',

View File

@@ -33,8 +33,6 @@ export interface Translation extends DefaultTranslation {
loading: string;
nextSlide: string;
numOptionsSelected: (num: number) => string;
pauseAnimation: string;
playAnimation: string;
previousSlide: string;
progress: string;
remove: string;