Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
1e26234
Inital craft-info-icon
brianjhanson Apr 8, 2026
585fb39
Replace AdminTable info icon
brianjhanson Apr 9, 2026
fb678cf
Deprecation warning
brianjhanson Apr 9, 2026
a9bf4fb
Only one info-icon at a time
brianjhanson Apr 9, 2026
4510e78
Update link field instructions with new icon
brianjhanson Apr 9, 2026
b758c92
Merge branch 'feature/update-tooltips' into feature/entry-type-index
brianjhanson Apr 9, 2026
4c6f69a
Port Entry Type and Fields index page
brianjhanson Apr 9, 2026
a088277
Make things more consistent
brianjhanson Apr 10, 2026
e9c4cb2
Remove extra prop
brianjhanson Apr 10, 2026
31b71da
Style "new" buttons
brianjhanson Apr 10, 2026
0adf5ec
Empty state
brianjhanson Apr 10, 2026
7521d84
Delete entry types
brianjhanson Apr 10, 2026
13f7dee
Deprecation messages
brianjhanson Apr 10, 2026
dc8c476
CSS grid cp-table
brianjhanson Apr 10, 2026
d7627d0
Translation and search icon badges
brianjhanson Apr 10, 2026
0c40084
A bit more table cleanup
brianjhanson Apr 10, 2026
ba6d673
Improve styling of usages
brianjhanson Apr 10, 2026
e9a1a9c
Minor styling updates
brianjhanson Apr 10, 2026
1934a1f
Initial port of volumes
brianjhanson Apr 10, 2026
bc13aa3
Reorder volumes
brianjhanson Apr 11, 2026
184f72b
Switching out columnHelper for our custom one
brianjhanson Apr 11, 2026
05bd363
Convert the image transforms page
brianjhanson Apr 11, 2026
901fc10
Filesystems
brianjhanson Apr 13, 2026
04d9d07
Remove the old template
brianjhanson Apr 13, 2026
1571689
Build assets
brianjhanson Apr 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion packages/craftcms-cp/src/components/button/button.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ export default class CraftButton extends LionButtonSubmit {
/** Set align-items for the content */
@property() align: 'start' | 'end' | 'center' = 'center';

@property() icon: string | null = null;

@state()
private _hasAccessibilityError: boolean = false;

Expand All @@ -96,7 +98,11 @@ export default class CraftButton extends LionButtonSubmit {
})}"
part="content"
>
<slot name="prefix" class="prefix" part="prefix"></slot>
<slot name="prefix" class="prefix" part="prefix">
${this.icon
? html`<craft-icon name="${this.icon}"></craft-icon>`
: nothing}
</slot>
<slot class="label" part="label"></slot>
<slot name="suffix" class="suffix" part="suffix"></slot>
</div>
Expand Down
21 changes: 12 additions & 9 deletions packages/craftcms-cp/src/components/chip/chip.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ export default css`
}

.cp-chip {
--_min-height: var(--c-chip-height, var(--c-size-control-sm));
display: inline-flex;
min-height: var(--c-chip-height, var(--c-size-control-sm));
min-width: auto;
border-radius: var(--c-chip-radius, var(--c-radius-md));
padding-inline: var(--c-chip-spacing-inline, var(--c-spacing-md));
padding-inline: var(--c-chip-spacing-inline, 0);
padding-block: var(--c-chip-spacing-block, var(--c-spacing-sm));
align-items: start;
box-shadow: var(--c-chip-shadow, var(--c-shadow-sm));
Expand All @@ -26,6 +26,12 @@ export default css`
background-color: var(--c-color-fill-quiet, var(--c-surface-raised));
}

.cp-chip__body ::slotted(a) {
text-decoration: none;
font-weight: bold;
display: flex;
}

.cp-chip[appearance='plain'],
.cp-chip--plain {
padding-block: 0;
Expand All @@ -37,8 +43,8 @@ export default css`

.cp-chip[size='small'],
.cp-chip--small {
padding-block: 0;
min-height: var(--c-size-control-sm);
--_min-height: var(--c-size-control-sm);
padding-block: calc(var(--c-spacing-xs) / 2);
}

.cp-chip[size='medium'],
Expand All @@ -52,6 +58,7 @@ export default css`
.cp-chip__suffix {
display: inline-flex;
flex-direction: column;
min-height: var(--_min-height);
}

.cp-chip__body {
Expand All @@ -62,14 +69,10 @@ export default css`
}

.cp-chip__prefix {
padding-inline-end: var(--c-spacing-md);
padding-inline: calc(var(--c-spacing-md) / 2);
}

.cp-chip__suffix {
padding-inline-start: var(--c-spacing-md);
}

:host(:not([variant='plain'])) .cp-chip__suffix {
margin-inline-end: calc(var(--c-spacing-sm) * -1);
}
`;
24 changes: 24 additions & 0 deletions packages/craftcms-cp/src/components/icon/icon.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,43 @@
import WaIcon from '@awesome.me/webawesome/dist/components/icon/icon.js';
import {css} from 'lit';
import {property} from 'lit/decorators.js';

/**
* craft-icon is just an alias to wa-icon from web awesome.
*
* Anything you can do over there you can do here.
*/
export default class CraftIcon extends WaIcon {
@property({reflect: true}) appearance?: 'plain' | 'badge' = 'plain';

override connectedCallback() {
super.connectedCallback();

if (this.appearance === 'badge' && !this.getAttribute('data-color')) {
this.setAttribute('data-color', 'warning');
}
}

static override get styles() {
return [
WaIcon.styles,
css`
:host {
font-size: 0.8em;
}

:host([appearance~='badge']) {
border: 1px solid var(--c-color-border-quiet);
color: var(--c-color-on-quiet);
background-color: var(--c-color-fill-quiet);
border-radius: var(--c-radius-sm);
width: 1.6em;
height: 1.6em;

svg {
width: 0.9em;
}
}
`,
];
}
Expand Down
36 changes: 36 additions & 0 deletions packages/craftcms-cp/src/components/info-icon/info-icon.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import type {Meta, StoryObj} from '@storybook/web-components-vite';
import './info-icon';

const meta: Meta = {
title: 'Components/Info Icon',
tags: ['autodocs'],
args: {},
render: (args) => {
return `
<craft-info-icon>
This is the content for the tooltip
</craft-info-icon>`;
},
};

export default meta;

type Story = StoryObj<any>;

export const Default: Story = {
args: {
label: 'More Info',
icon: 'circle-info',
},
};

export const Multiple: Story = {
render: () => {
return `
<div style="display: flex; gap: 2rem; align-items: center;">
<craft-info-icon>Tooltip content for icon 1</craft-info-icon>
<craft-info-icon>Tooltip content for icon 2</craft-info-icon>
<craft-info-icon>Tooltip content for icon 3</craft-info-icon>
</div>`;
},
};
122 changes: 122 additions & 0 deletions packages/craftcms-cp/src/components/info-icon/info-icon.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import {t} from '@src/utilities/translate';
import {html, LitElement} from 'lit';
import {property, query, queryAssignedElements, state} from 'lit/decorators.js';

import '../button/button';
import '../icon/icon';
import '../tooltip/tooltip';
import type CraftTooltip from '../tooltip/tooltip';
import '../visually-hidden/visually-hidden';

export default class CraftInfoIcon extends LitElement {
static #openInstance: CraftInfoIcon | null = null;

@property() label = t('More Info');

@property() icon = 'circle-info';

@property({type: Boolean, reflect: true}) disabled = false;

@property() override id: string;

@state() status = '';

@query('c-tooltip') tooltip!: HTMLElement;

#eventController = new AbortController();

override connectedCallback() {
super.connectedCallback();

// Recreate event controller if it was aborted
if (this.#eventController.signal.aborted) {
this.#eventController = new AbortController();
}

if (!this.id) {
this.id = `info-icon-${Math.random().toString(36).slice(2, 8)}`;
}

const {signal} = this.#eventController;

this.addEventListener(
'wa-show',
() => {
if (
CraftInfoIcon.#openInstance &&
CraftInfoIcon.#openInstance !== this
) {
const otherTooltip =
CraftInfoIcon.#openInstance.renderRoot.querySelector<CraftTooltip>(
'c-tooltip'
);
otherTooltip?.hide();
}
CraftInfoIcon.#openInstance = this;
},
{signal}
);

this.addEventListener(
'wa-after-show',
() => {
this.status = '';
setTimeout(() => {
this.status = 'Some new status';
}, 200);
},
{signal}
);

this.addEventListener(
'wa-after-hide',
() => {
if (CraftInfoIcon.#openInstance === this) {
CraftInfoIcon.#openInstance = null;
}
this.status = '';
},
{signal}
);
}

override disconnectedCallback() {
if (CraftInfoIcon.#openInstance === this) {
CraftInfoIcon.#openInstance = null;
}
this.#eventController.abort();
super.disconnectedCallback();
}

override render() {
return html`
<div class="cp-info-icon">
<craft-visually-hidden role="status">
${this.status}
</craft-visually-hidden>

<craft-button
type="button"
icon
size="zero"
appearance="plain"
id="${this.id}"
>
<craft-icon name="${this.icon}" label="${this.label}"></craft-icon>
</craft-button>

<c-tooltip trigger="click" for="${this.id}"><slot></slot></c-tooltip>
</div>
`;
}
}

if (!customElements.get('craft-info-icon')) {
customElements.define('craft-info-icon', CraftInfoIcon);
}

declare global {
interface HTMLElementTagNameMap {
'craft-info-icon': CraftInfoIcon;
}
}
4 changes: 3 additions & 1 deletion packages/craftcms-cp/src/components/spinner/spinner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import {property, query} from 'lit/decorators.js';
import componentStyles from './spinner.styles.js';
import {classMap} from 'lit/directives/class-map.js';

import '../visually-hidden/visually-hidden';

export default class CraftSpinner extends LitElement {
static override styles = [componentStyles];

Expand Down Expand Up @@ -36,7 +38,7 @@ export default class CraftSpinner extends LitElement {
})}"
>
<div class="spinner"></div>
<span class="message visually-hidden"><slot /></span>
<visually-hidden class="message"><slot></slot></span>
</div>
`;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import {css, html, LitElement} from 'lit';
import CraftInfoIcon from '@src/components/info-icon/info-icon';
import {property} from 'lit/decorators.js';

export default class CraftVisuallyHidden extends LitElement {
static override styles = css`
:host(:not([debug])) {
position: absolute;
width: 1px;
height: 1px;
overflow: hidden;
clip: rect(0 0 0 0);
clip-path: inset(50%);
white-space: nowrap;
}
`;

@property({type: Boolean, reflect: true}) debug = false;

protected override render(): unknown {
return html`<slot></slot>`;
}
}

if (!customElements.get('craft-visually-hidden')) {
customElements.define('craft-visually-hidden', CraftVisuallyHidden);
}

declare global {
interface HTMLElementTagNameMap {
'craft-visually-hidden': CraftVisuallyHidden;
}
}
2 changes: 2 additions & 0 deletions packages/craftcms-cp/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export {default as CraftSelect} from './components/select/select.js';
export {default as CraftOption} from './components/option/option.js';
export {default as CraftDropdown} from './components/dropdown/dropdown.js';
export {default as CraftIcon} from './components/icon/icon.js';
export {default as CraftInfoIcon} from './components/info-icon/info-icon.js';
export {default as CraftTabs} from './components/tabs/tabs.js';
export {default as CraftCard} from './components/card/card.js';
export {default as CraftTab} from './components/tab/tab.js';
Expand All @@ -46,6 +47,7 @@ export {default as CraftProgress} from './components/progress/progress.js';
export {default as CraftProgressBar} from './components/progress-bar/progress-bar.js';
export {default as CraftRadioGroup} from './components/radio-group/radio-group.js';
export {default as CraftRadio} from './components/radio/radio.js';
export {default as CraftVisuallyHidden} from './components/visually-hidden/visually-hidden.js';
/* plop:component */

export * from './utilities/cookies.js';
Expand Down
9 changes: 7 additions & 2 deletions packages/craftcms-cp/src/styles/form.styles.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import {css} from 'lit';

export const baseInputStyles = css`
--_border-width: var(
--c-input-border-width,
var(--c-form-control-border-width)
);
--_min-height: var(--c-input-height, var(--c-size-control-md));
font: inherit;
color: var(--c-input-text, var(--c-text-default));
position: relative;
min-height: var(--c-input-height, var(--c-size-control-md));
border-width: var(--c-input-border-width, var(--c-form-control-border-width));
min-height: calc(var(--_min-height) - 2 * var(--_border-width));
border-width: var(--_border-width);
border-style: var(--c-input-border-style, var(--c-form-control-border-style));
border-color: var(--c-input-border-color, var(--c-form-control-border-color));
border-radius: var(--c-input-radius, var(--c-radius-sm));
Expand Down
Loading
Loading