Skip to content

Commit

Permalink
feat: Add new component to toolbar library (#10906)
Browse files Browse the repository at this point in the history
* feat: progress

* chore: changeset
  • Loading branch information
Princesseuh authored May 8, 2024
1 parent ddd8e49 commit 7bbd664
Show file tree
Hide file tree
Showing 7 changed files with 168 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/metal-crabs-applaud.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"astro": minor
---

Adds a new radio checkbox component to the dev toolbar UI library (`astro-dev-toolbar-radio-checkbox`)
5 changes: 5 additions & 0 deletions .changeset/twelve-dolphins-roll.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"astro": minor
---

Adds a new `buttonBorderRadius` property to the `astro-dev-toolbar-button` component for the dev toolbar component library. This property can be useful to make a fully rounded button with an icon in the center.
2 changes: 2 additions & 0 deletions packages/astro/src/@types/astro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import type {
DevToolbarCard,
DevToolbarHighlight,
DevToolbarIcon,
DevToolbarRadioCheckbox,
DevToolbarSelect,
DevToolbarToggle,
DevToolbarTooltip,
Expand Down Expand Up @@ -3087,6 +3088,7 @@ declare global {
'astro-dev-toolbar-icon': DevToolbarIcon;
'astro-dev-toolbar-card': DevToolbarCard;
'astro-dev-toolbar-select': DevToolbarSelect;
'astro-dev-toolbar-radio-checkbox': DevToolbarRadioCheckbox;

// Deprecated names
// TODO: Remove in Astro 5.0
Expand Down
2 changes: 2 additions & 0 deletions packages/astro/src/runtime/client/dev-toolbar/entrypoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ document.addEventListener('DOMContentLoaded', async () => {
DevToolbarBadge,
DevToolbarIcon,
DevToolbarSelect,
DevToolbarRadioCheckbox,
},
] = await Promise.all([
loadDevToolbarApps() as DevToolbarAppDefinition[],
Expand All @@ -48,6 +49,7 @@ document.addEventListener('DOMContentLoaded', async () => {
customElements.define('astro-dev-toolbar-badge', DevToolbarBadge);
customElements.define('astro-dev-toolbar-icon', DevToolbarIcon);
customElements.define('astro-dev-toolbar-select', DevToolbarSelect);
customElements.define('astro-dev-toolbar-radio-checkbox', DevToolbarRadioCheckbox);

// Add deprecated names
// TODO: Remove in Astro 5.0
Expand Down
35 changes: 32 additions & 3 deletions packages/astro/src/runtime/client/dev-toolbar/ui-library/button.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@ import { settings } from '../settings.js';

const sizes = ['small', 'medium', 'large'] as const;
const styles = ['ghost', 'outline', 'purple', 'gray', 'red', 'green', 'yellow', 'blue'] as const;
const borderRadii = ['normal', 'rounded'] as const;

type ButtonSize = (typeof sizes)[number];
type ButtonStyle = (typeof styles)[number];
type ButtonBorderRadius = (typeof borderRadii)[number];

export class DevToolbarButton extends HTMLElement {
_size: ButtonSize = 'small';
_buttonStyle: ButtonStyle = 'purple';
_buttonBorderRadius: ButtonBorderRadius = 'normal';

get size() {
return this._size;
Expand Down Expand Up @@ -40,7 +43,22 @@ export class DevToolbarButton extends HTMLElement {
this.updateStyle();
}

static observedAttributes = ['button-style', 'size'];
get buttonBorderRadius() {
return this._buttonBorderRadius;
}

set buttonBorderRadius(value) {
if (!borderRadii.includes(value)) {
settings.logger.error(
`Invalid border-radius: ${value}, expected one of ${borderRadii.join(', ')}, got ${value}.`
);
return;
}
this._buttonBorderRadius = value;
this.updateStyle();
}

static observedAttributes = ['button-style', 'size', 'button-border-radius'];

shadowRoot: ShadowRoot;

Expand Down Expand Up @@ -88,16 +106,22 @@ export class DevToolbarButton extends HTMLElement {
--small-font-size: 12px;
--large-padding: 12px 16px;
--large-rounded-padding: 12px 12px;
--medium-padding: 8px 12px;
--medium-rounded-padding: 8px 8px;
--small-padding: 4px 8px;
--small-rounded-padding: 4px 4px;
--normal-border-radius: 4px;
--rounded-border-radius: 9999px;
border: 1px solid var(--border);
padding: var(--padding);
font-size: var(--font-size);
background: var(--background);
color: var(--text-color);
border-radius: 4px;
border-radius: var(--border-radius);
display: flex;
align-items: center;
justify-content: center;
Expand Down Expand Up @@ -137,8 +161,13 @@ export class DevToolbarButton extends HTMLElement {
--background: var(--${this.buttonStyle}-background);
--border: var(--${this.buttonStyle}-border);
--font-size: var(--${this.size}-font-size);
--padding: var(--${this.size}-padding);
--text-color: var(--${this.buttonStyle}-text);
${
this.buttonBorderRadius === 'normal'
? '--padding: var(--' + this.size + '-padding);'
: '--padding: var(--' + this.size + '-rounded-padding);'
}
--border-radius: var(--${this.buttonBorderRadius}-border-radius);
}`;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ export { DevToolbarSelect } from './select.js';
export { DevToolbarToggle } from './toggle.js';
export { DevToolbarTooltip } from './tooltip.js';
export { DevToolbarWindow } from './window.js';
export { DevToolbarRadioCheckbox } from './radio-checkbox.js';
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
const styles = ['purple', 'gray', 'red', 'green', 'yellow', 'blue'] as const;

type RadioStyle = (typeof styles)[number];

export class DevToolbarRadioCheckbox extends HTMLElement {
private _radioStyle: RadioStyle = 'purple';
input: HTMLInputElement;

shadowRoot: ShadowRoot;

get radioStyle() {
return this._radioStyle;
}

set radioStyle(value) {
if (!styles.includes(value)) {
console.error(`Invalid style: ${value}, expected one of ${styles.join(', ')}.`);
return;
}
this._radioStyle = value;
this.updateStyle();
}

static observedAttributes = ['radio-style', 'checked', 'disabled', 'name', 'value'];

constructor() {
super();
this.shadowRoot = this.attachShadow({ mode: 'open' });

this.shadowRoot.innerHTML = `
<style>
:host {
--purple-unchecked: rgba(224, 204, 250, 0.33);
--purple-checked: rgba(224, 204, 250, 1);
--gray-unchecked: rgba(191, 193, 201, 0.33);
--gray-checked: rgba(191, 193, 201, 1);
--red-unchecked: rgba(249, 196, 215, 0.33);
--red-checked: rgba(179, 62, 102, 1);
--green-unchecked: rgba(213, 249, 196, 0.33);
--green-checked: rgba(61, 125, 31, 1);
--yellow-unchecked: rgba(255, 236, 179, 0.33);
--yellow-checked: rgba(181, 138, 45, 1);
--blue-unchecked: rgba(189, 195, 255, 0.33);
--blue-checked: rgba(54, 69, 217, 1);
}
input[type="radio"] {
appearance: none;
-webkit-appearance: none;
display: flex;
align-content: center;
justify-content: center;
border: 2px solid var(--unchecked-color);
border-radius: 9999px;
width: 16px;
height: 16px;
}
input[type="radio"]::before {
content: "";
background-color: var(--checked-color);
width: 8px;
height: 8px;
border-radius: 9999px;
visibility: hidden;
margin: 2px;
}
input[type="radio"]:checked {
border-color: var(--checked-color);
}
input[type="radio"]:checked::before {
visibility: visible;
}
</style>
<style id="selected-style"></style>
`;
this.input = document.createElement('input');
this.input.type = 'radio';
this.shadowRoot.append(this.input);
}

connectedCallback() {
this.updateInputState();
this.updateStyle();
}

updateStyle() {
const styleElement = this.shadowRoot.querySelector<HTMLStyleElement>('#selected-style');

if (styleElement) {
styleElement.innerHTML = `
:host {
--unchecked-color: var(--${this._radioStyle}-unchecked);
--checked-color: var(--${this._radioStyle}-checked);
}
`;
}
}

updateInputState() {
this.input.checked = this.hasAttribute('checked');
this.input.disabled = this.hasAttribute('disabled');
this.input.name = this.getAttribute('name') || '';
this.input.value = this.getAttribute('value') || '';
}

attributeChangedCallback() {
if (this.hasAttribute('radio-style')) {
this.radioStyle = this.getAttribute('radio-style') as RadioStyle;
}

this.updateInputState();
}
}

0 comments on commit 7bbd664

Please sign in to comment.