Compare commits

..

9 Commits

Author SHA1 Message Date
konnorrogers
18e5612564 Merge branch 'next' of https://github.com/shoelace-style/webawesome into slider-fix 2025-12-16 11:00:07 -05:00
Konnor Rogers
3d395653fc Bug fix: el.form = 'foo' no longer sets the el.form property (#1815)
* Bug fix: el.form = 'foo' no longer sets the el.form property

* add changelog entry

* add changelog entry

* prettier

* fix form

* skip style attr for button

* prettier
2025-12-16 10:59:40 -05:00
konnorrogers
99c6e68aa4 Merge branch 'next' of https://github.com/shoelace-style/webawesome into slider-fix 2025-12-16 10:56:47 -05:00
Konnor Rogers
b3844ef77f fixing deploy scripts, and updating root version (#1857)
* fixing deploy scripts

* update root version script

* prettier
2025-12-16 10:29:26 -05:00
Lindsay M
a50648c6e8 Update changelog with leftover items (#1874)
* add leftover logs

* remove video component log
2025-12-15 17:49:56 -05:00
Cory LaViska
b6b82fb0ac Revert "updated sidebar (#1873)" (#1875)
This reverts commit fa073e8d21.
2025-12-15 15:59:38 -05:00
Kelsey Jackson
fa073e8d21 updated sidebar (#1873)
* updated sidebar

* added video item

* fixed formatting

* update

---------

Co-authored-by: Cory LaViska <cory@abeautifulsite.net>
2025-12-15 15:01:32 -05:00
Cory LaViska
e0f6ff11ec Combobox (supporting contributions in free) (#1838)
* hold the mustard! let's make it yellower

* words

* update sidebar

* update changelog

* fix icon cropping

* add combobox support

* preserve user-selected order

* add quick pro flag

* move import to the top

* fix custom tag example
2025-12-11 13:04:42 -05:00
Cory LaViska
6403588285 ensure min/max/step are numbers; fixes #1823 2025-11-26 10:17:30 -05:00
15 changed files with 95 additions and 74 deletions

18
package-lock.json generated
View File

@@ -14053,7 +14053,8 @@
"devDependencies": {
"@wc-toolkit/jsx-types": "^1.3.0",
"eleventy-plugin-git-commit-date": "^0.1.3",
"esbuild": "^0.25.11"
"esbuild": "^0.25.11",
"npm-check-updates": "^19.1.2"
},
"engines": {
"node": ">=14.17.0"
@@ -14526,6 +14527,21 @@
"node": "^18 || >=20"
}
},
"packages/webawesome-pro/node_modules/npm-check-updates": {
"version": "19.1.2",
"resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-19.1.2.tgz",
"integrity": "sha512-FNeFCVgPOj0fz89hOpGtxP2rnnRHR7hD2E8qNU8SMWfkyDZXA/xpgjsL3UMLSo3F/K13QvJDnbxPngulNDDo/g==",
"dev": true,
"license": "Apache-2.0",
"bin": {
"ncu": "build/cli.js",
"npm-check-updates": "build/cli.js"
},
"engines": {
"node": ">=20.0.0",
"npm": ">=8.12.1"
}
},
"packages/webawesome/node_modules/@esbuild/aix-ppc64": {
"version": "0.25.11",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.11.tgz",

View File

@@ -2,7 +2,7 @@
"name": "@webawesome/monorepo",
"private": true,
"description": "A forward-thinking library of web components.",
"version": "3.0.0-alpha.13",
"version": "3.0.0",
"homepage": "https://webawesome.com/",
"author": "Web Awesome",
"license": "MIT",
@@ -85,4 +85,4 @@
"prettier --write"
]
}
}
}

View File

@@ -14,6 +14,8 @@ Components with the <wa-badge variant="warning">Experimental</wa-badge> badge sh
## Next
- Added `<wa-combobox>` as an experimental pro component [issue:1074]
- Added version 2.0.0 of the [official Web Awesome Figma Design Kit](/docs/resources/figma)
- Added npm support for Web Awesome Pro
- Added `layers.css` to define cascade layer order and updated palettes, themes, native styles, and utilities to import the new rule for more fail-safe modularity [pr:1793]
- Fixed a bug in `<wa-slider>` that caused some touch devices to end up with the incorrect value [issue:1703]
- Fixed a bug in `<wa-card>` that prevented some slots from being detected correctly [discuss:1450]
@@ -25,6 +27,9 @@ Components with the <wa-badge variant="warning">Experimental</wa-badge> badge sh
- Fixed a bug in `<wa-select>` that prevented clicks on the tag's remove button from removing options in multiple mode
- Fixed a bug in `<wa-select>` that caused tags to appear in alphabetical order instead of selection order when using `multiple`
- Improved performance of `<wa-icon>` so initial rendering occurs faster, especially with multiple icons on the page [issue:1729]
- Improved `<wa-slider>` to not throw an error when string values are passed to the `min`, `max`, and `step` properties [issue:1823]
- Fixed a bug in Web Awesome form controls that caused `<wa-input form="foo">` to set the form property to equal `"foo"` instead of returning an `HTMLFormElement` breaking platform expectations. [pr:1815]
- Fixed a bug in `<wa-button>` causing it to not copy over attributes for form submissions. [pr:1815]
- Improved performance of all components by fixing how CSS is imported and reused [issue:1812]
- Modified the default `transition` styles of `<wa-dropdown-item>` to use design tokens [pr:1693]
@@ -510,4 +515,4 @@ Many of these changes and improvements were the direct result of feedback from u
</details>
Did we miss something? [Let us know!](https://github.com/shoelace-style/webawesome/discussions)
Did we miss something? [Let us know!](https://github.com/shoelace-style/webawesome/discussions)

View File

@@ -67,7 +67,7 @@
"check-updates": "npm-check-updates --cooldown 7 --interactive --format group",
"print-version": "echo $npm_package_version",
"tag-version": "git tag -a \"v$(npm run print-version | tail -n1)\" -m \"tag v$(npm run print-version | tail -n1)\"",
"postversion": "npm run tag-version"
"postversion": "npm run tag-version && node ./scripts/update-root-version.js"
},
"engines": {
"node": ">=14.17.0"

View File

@@ -0,0 +1,27 @@
#!/usr/bin/env node
import * as fs from 'node:fs';
import * as path from 'node:path';
import * as url from 'url';
const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
const monorepoRoot = path.resolve(__dirname, '..', '..', '..');
const rootPackageJSONFile = path.join(monorepoRoot, 'package.json');
const webawesomePackageJSONFile = path.join(path.resolve(__dirname, '..'), 'package.json');
const rootPackageJSON = JSON.parse(fs.readFileSync(rootPackageJSONFile));
const webawesomePackageJSON = JSON.parse(fs.readFileSync(webawesomePackageJSONFile));
const currentVersion = webawesomePackageJSON.version;
rootPackageJSON.version = currentVersion;
fs.writeFileSync(rootPackageJSONFile, JSON.stringify(rootPackageJSON, null, 2));
const versionsFile = path.join(monorepoRoot, 'VERSIONS.txt');
const versions = fs.readFileSync(versions).split(/\r?\n/);
// TODO: Make this smart and understand semver and "insert" in the correct spot instead of appending.
if (!versions.includes(currentVersion)) {
fs.appendFileSync(webawesomePackageJSON.version);
}

View File

@@ -115,7 +115,6 @@ export default class WaButton extends WebAwesomeFormAssociatedElement {
* The "form owner" to associate the button with. If omitted, the closest containing form will be used instead. The
* value of this attribute must be an id of a form in the same document or shadow root as the button.
*/
@property({ reflect: true }) form: string | null = null;
/** Used to override the form owner's `action` attribute. */
@property({ attribute: 'formaction' }) formAction: string;
@@ -135,24 +134,27 @@ export default class WaButton extends WebAwesomeFormAssociatedElement {
private constructLightDOMButton() {
const button = document.createElement('button');
for (const attribute of this.attributes) {
if (attribute.name === 'style') {
// Skip style attributes as they *shouldn't* be necessary
continue;
}
button.setAttribute(attribute.name, attribute.value);
}
button.type = this.type;
button.style.position = 'absolute';
button.style.width = '0';
button.style.height = '0';
button.style.clipPath = 'inset(50%)';
button.style.overflow = 'hidden';
button.style.whiteSpace = 'nowrap';
button.style.position = 'absolute !important';
button.style.width = '0 !important';
button.style.height = '0 !important';
button.style.clipPath = 'inset(50%) !important';
button.style.overflow = 'hidden !important';
button.style.whiteSpace = 'nowrap !important';
if (this.name) {
button.name = this.name;
}
button.value = this.value || '';
['form', 'formaction', 'formenctype', 'formmethod', 'formnovalidate', 'formtarget'].forEach(attr => {
if (this.hasAttribute(attr)) {
button.setAttribute(attr, this.getAttribute(attr)!);
}
});
return button;
}

View File

@@ -108,13 +108,6 @@ export default class WaCheckbox extends WebAwesomeFormAssociatedElement {
@property({ type: Boolean, reflect: true, attribute: 'checked' }) defaultChecked: boolean =
this.hasAttribute('checked');
/**
* By default, form controls are associated with the nearest containing `<form>` element. This attribute allows you
* to place the form control outside of a form and associate it with the form that has this `id`. The form must be in
* the same document or shadow root for this to work.
*/
@property({ reflect: true }) form = null;
/** Makes the checkbox a required field. */
@property({ type: Boolean, reflect: true }) required = false;

View File

@@ -220,13 +220,6 @@ export default class WaColorPicker extends WebAwesomeFormAssociatedElement {
*/
@property() swatches: string | string[] = '';
/**
* By default, form controls are associated with the nearest containing `<form>` element. This attribute allows you
* to place the form control outside of a form and associate it with the form that has this `id`. The form must be in
* the same document or shadow root for this to work.
*/
@property({ reflect: true }) form = null;
/** Makes the color picker a required field. */
@property({ type: Boolean, reflect: true }) required = false;

View File

@@ -140,13 +140,6 @@ export default class WaInput extends WebAwesomeFormAssociatedElement {
/** Hides the browser's built-in increment/decrement spin buttons for number inputs. */
@property({ attribute: 'without-spin-buttons', type: Boolean }) withoutSpinButtons = false;
/**
* By default, form controls are associated with the nearest containing `<form>` element. This attribute allows you
* to place the form control outside of a form and associate it with the form that has this `id`. The form must be in
* the same document or shadow root for this to work.
*/
@property({ reflect: true }) form = null;
/** Makes the input a required field. */
@property({ type: Boolean, reflect: true }) required = false;

View File

@@ -39,11 +39,6 @@ export default class WaRadio extends WebAwesomeFormAssociatedElement {
/** @internal Used by radio group to force disable radios while preserving their original disabled state. */
@state() forceDisabled = false;
/**
* The string pointing to a form's id.
*/
@property({ reflect: true }) form: string | null = null;
/** The radio's value. When selected, the radio group will receive this value. */
@property({ reflect: true }) value: string;

View File

@@ -257,13 +257,6 @@ export default class WaSelect extends WebAwesomeFormAssociatedElement {
*/
@property({ attribute: 'with-hint', type: Boolean }) withHint = false;
/**
* By default, form controls are associated with the nearest containing `<form>` element. This attribute allows you
* to place the form control outside of a form and associate it with the form that has this `id`. The form must be in
* the same document or shadow root for this to work.
*/
@property({ reflect: true }) form = null;
/** The select's required attribute. */
@property({ type: Boolean, reflect: true }) required = false;

View File

@@ -167,12 +167,6 @@ export default class WaSlider extends WebAwesomeFormAssociatedElement {
/** The starting value from which to draw the slider's fill, which is based on its current value. */
@property({ attribute: 'indicator-offset', type: Number }) indicatorOffset: number;
/**
* The form to associate this control with. If omitted, the closest containing `<form>` will be used. The value of
* this attribute must be an ID of a form in the same document or shadow root.
*/
@property({ reflect: true }) form = null;
/** The minimum value allowed. */
@property({ type: Number }) min: number = 0;
@@ -437,8 +431,14 @@ export default class WaSlider extends WebAwesomeFormAssociatedElement {
/** Clamps a number to min/max while ensuring it's a valid step interval. */
private clampAndRoundToStep(value: number) {
const stepPrecision = (String(this.step).split('.')[1] || '').replace(/0+$/g, '').length;
value = Math.round(value / this.step) * this.step;
value = clamp(value, this.min, this.max);
// Ensure we're working with numbers (in case the user passes strings to the respective properties)
const step = Number(this.step);
const min = Number(this.min);
const max = Number(this.max);
value = Math.round(value / step) * step;
value = clamp(value, min, max);
return parseFloat(value.toFixed(stepPrecision));
}

View File

@@ -80,13 +80,6 @@ export default class WaSwitch extends WebAwesomeFormAssociatedElement {
@property({ type: Boolean, attribute: 'checked', reflect: true }) defaultChecked: boolean =
this.hasAttribute('checked');
/**
* By default, form controls are associated with the nearest containing `<form>` element. This attribute allows you
* to place the form control outside of a form and associate it with the form that has this `id`. The form must be in
* the same document or shadow root for this to work.
*/
@property({ reflect: true }) form = null;
/** Makes the switch a required field. */
@property({ type: Boolean, reflect: true }) required = false;

View File

@@ -107,13 +107,6 @@ export default class WaTextarea extends WebAwesomeFormAssociatedElement {
/** Makes the textarea readonly. */
@property({ type: Boolean, reflect: true }) readonly = false;
/**
* By default, form controls are associated with the nearest containing `<form>` element. This attribute allows you
* to place the form control outside of a form and associate it with the form that has this `id`. The form must be in
* the same document or shadow root for this to work.
*/
@property({ reflect: true }) form = null;
/** Makes the textarea a required field. */
@property({ type: Boolean, reflect: true }) required = false;

View File

@@ -23,7 +23,8 @@ export interface WebAwesomeFormControl extends WebAwesomeElement {
checked?: boolean;
defaultSelected?: boolean;
selected?: boolean;
form?: string | null;
get form(): HTMLFormElement | null;
set form(val: string);
value?: unknown;
@@ -203,6 +204,23 @@ export class WebAwesomeFormAssociatedElement
return this.internals.form;
}
/**
* By default, form controls are associated with the nearest containing `<form>` element. This attribute allows you
* to place the form control outside of a form and associate it with the form that has this `id`. The form must be in
* the same document or shadow root for this to work.
*/
set form(val: string) {
if (val) {
this.setAttribute('form', val);
} else {
this.removeAttribute('form');
}
}
get form(): HTMLFormElement | null {
return this.internals.form;
}
@property({ attribute: false, state: true, type: Object })
get validity() {
return this.internals.validity;