name and value props are submitted as a pair as part of the form data.<!doctype html>
<html lang="en" class="scheme-light-dark">
<head>
<title></title>
</head>
<body class="bg-canvas">
<form class="flex gap-fluid-sm">
<p-button name="option" value="A" type="submit">Button A</p-button>
<p-button name="option" value="B" type="submit">Button B</p-button>
</form>
<p-text>Last submitted data: none</p-text>
<script>
const debugElement = document.querySelector('p-text');
const form = document.querySelector('form');
form.addEventListener('submit', (e) => {
e.preventDefault();
const formData = Array.from(new FormData(e.target, e.submitter).entries())[0];
debugElement.innerText = `Last submitted data: ${formData.join('=') || 'none'}`;
});
</script>
</body>
</html>form attribute can be utilized to explicitly
associate the button with a specific form element.Attention
p-button component as a submit or reset button outside a
form, it relies on the
ElementInternals API, which has
limited browser support.As of now, the submitter in the form event is null because the button cannot be accessed within the shadow DOM to be passed as an argument to the
requestSubmit() function (
WICG/webcomponents#814).<!doctype html>
<html lang="en" class="scheme-light-dark">
<head>
<title></title>
</head>
<body class="bg-canvas">
<form id="some-form">
<p-textarea name="some-name" label="Some Label"></p-textarea>
</form>
<div class="flex gap-fluid-sm mt-fluid-sm">
<p-button type="submit" form="some-form">Submit</p-button>
<p-button type="reset" form="some-form">Reset</p-button>
</div>
<p-text>Last submitted data: none</p-text>
<script>
const debugElement = document.querySelector('p-text');
const form = document.querySelector('form');
form.addEventListener('submit', (e) => {
e.preventDefault();
const formData = new FormData(form);
debugElement.innerText = `Last submitted data: ${formData.get('some-name') || 'none'} `;
});
</script>
</body>
</html>--p-button-bg and --p-button-fg
CSS variables. It is not approved by brand compliance and must not be treated as an official AI button style.--p-shadow-lg token. Hover is scoped with :not(:disabled, :state(loading)) so the styling isn't applied while the
button is disabled or loading.<!doctype html>
<html lang="en" class="scheme-light-dark">
<head>
<title></title>
</head>
<body class="bg-canvas">
<style>
.custom-ai-shadow {
--p-button-bg: #fff;
--p-button-fg: #000;
box-shadow: var(--p-shadow-lg);
}
.custom-ai-shadow:not(:disabled, :state(loading)):hover {
--p-button-bg: var(--p-color-frosted-strong);
--p-button-fg: var(--p-color-primary);
}
</style>
<div class="flex flex-wrap gap-static-lg items-start">
<p-button class="custom-ai-shadow" icon="ai-chat" hide-label="true">
Ask AI assistant
</p-button>
<p-button class="custom-ai-shadow" icon="ai-chat">
Ask AI assistant
</p-button>
</div>
<script>
</script>
</body>
</html>::before and ::after) on the p-button
host. They sit behind the button via z-index: -1 and reuse its shape with border-radius: inherit, so the button's
own shadow DOM, focus ring and keyboard behavior stay untouched.@media (prefers-reduced-motion: reduce) for users who requested reduced motion.@media (forced-colors: active), since the gradient carries no meaning
and would otherwise be flattened to a system color in High Contrast Mode.<!doctype html>
<html lang="en" class="scheme-light-dark">
<head>
<title></title>
</head>
<body class="bg-canvas">
<style>
.custom-ai-orb {
--p-button-bg: var(--p-color-canvas);
--p-button-fg: var(--p-color-primary);
position: relative;
z-index: 0;
}
.custom-ai-orb:not(:disabled, :state(loading)):hover {
--p-button-bg: var(--p-color-frosted-strong);
--p-button-fg: #fff;
}
.custom-ai-orb::before,
.custom-ai-orb::after {
content: '';
position: absolute;
inset: 0;
z-index: -1;
border-radius: inherit;
background: linear-gradient(45deg, #00a8ff, #0151e1, #2ae3ff, #bff0ff, #0151e1, #00a8ff);
background-size: 400%;
animation: custom-ai-orb-gradient 20s linear infinite;
}
.custom-ai-orb::after {
filter: blur(10px);
animation:
custom-ai-orb-gradient 20s linear infinite,
custom-ai-orb-float 8s ease-in-out infinite;
}
@keyframes custom-ai-orb-gradient {
0% {
background-position: 0 0;
}
50% {
background-position: 300% 0;
}
100% {
background-position: 0 0;
}
}
@keyframes custom-ai-orb-float {
0% {
transform: scale(1) rotate(0deg);
}
50% {
transform: scale(1.02) rotate(0.5deg);
}
100% {
transform: scale(1) rotate(0deg);
}
}
/* Respect the user's motion preference */
@media (prefers-reduced-motion: reduce) {
.custom-ai-orb::before,
.custom-ai-orb::after {
animation: none;
}
}
/* Decorative gradient is not conveyed in forced-colors mode */
@media (forced-colors: active) {
.custom-ai-orb::before,
.custom-ai-orb::after {
display: none;
}
}
</style>
<div class="flex flex-wrap gap-static-lg items-start">
<p-button class="custom-ai-orb" icon="ai-chat" hide-label="true">
Ask AI assistant
</p-button>
<p-button class="custom-ai-orb" icon="ai-chat">
Ask AI assistant
</p-button>
</div>
<script>
</script>
</body>
</html>