Skip to content

Commit 624d6a4

Browse files
element: ak-hint (#57)
* Moved the hint over. It's straightforward. * Fixed some CSS and test issues. * Hints are now themable. * Bringing hint into the modern world. * Hint has been updated, modernized, fixed and generally improved.
1 parent 01d2daf commit 624d6a4

File tree

10 files changed

+1065
-2
lines changed

10 files changed

+1065
-2
lines changed

src/ak-hint/ak-hint.builder.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import type { ElementRest } from "../types.js";
2+
import { Hint, type HintVariant } from "./ak-hint.component.js";
3+
4+
import { spread } from "@open-wc/lit-helpers";
5+
6+
import { html, nothing, TemplateResult } from "lit";
7+
import { ifDefined } from "lit/directives/if-defined.js";
8+
9+
export type HintProps = ElementRest & {
10+
variant?: HintVariant;
11+
// Must be named "hint"; although it's called "title" everywhere else, "title" as a field name
12+
// conflicts with HTMLElement.title by type.
13+
hint?: string | TemplateResult;
14+
footer?: string | TemplateResult;
15+
body?: string | TemplateResult;
16+
};
17+
18+
/**
19+
* @summary Helper function to create a Hint component programmatically
20+
*
21+
* @returns {TemplateResult} A Lit template result containing the configured ak-hint element
22+
*
23+
* @see {@link Hint} - The underlying web component
24+
*/
25+
26+
export function akHint(options: HintProps = {}) {
27+
const { hint, body, footer, variant, ...rest } = options;
28+
29+
return html`
30+
<ak-hint ${spread(rest)} variant=${ifDefined(variant)}>
31+
${hint ? html`<h3 slot="title">${hint}</h3>` : nothing}
32+
${body ? html`<span>${body}</span>` : nothing}
33+
${footer ? html`<footer slot="footer">${footer}</footer>` : nothing}
34+
</ak-hint>
35+
`;
36+
}

src/ak-hint/ak-hint.component.ts

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import { AkLitElement } from "../component-base.js";
2+
import styles from "./ak-hint.css";
3+
4+
import { html, nothing } from "lit";
5+
6+
// Used only by the builder, as these have only visual effects
7+
export const hintVariant = ["info", "success", "warning", "danger"] as const;
8+
export type HintVariant = (typeof hintVariant)[number];
9+
10+
/**
11+
* @element ak-hint
12+
*
13+
* @summary A container for displaying informative content with optional title and footer sections
14+
*
15+
* @attr {string} variant - Visual theme variant: "info" (default), "success", "warning", "danger"
16+
*
17+
* @slot - Main content body of the hint
18+
* @slot title - Optional title header for the hint
19+
* @slot footer - Optional footer content with additional information or actions
20+
*
21+
* @csspart hint - The hint component as a whole
22+
* @csspart title - The title section container
23+
* @csspart body - The main content body container
24+
* @csspart footer - The footer section container
25+
*
26+
* @cssprop --pf-v5-c-hint--GridRowGap - Gap between grid rows
27+
* @cssprop --pf-v5-c-hint--PaddingTop - Top padding of the hint container
28+
* @cssprop --pf-v5-c-hint--PaddingRight - Right padding of the hint container
29+
* @cssprop --pf-v5-c-hint--PaddingBottom - Bottom padding of the hint container
30+
* @cssprop --pf-v5-c-hint--PaddingLeft - Left padding of the hint container
31+
* @cssprop --pf-v5-c-hint--BackgroundColor - Background color of the hint
32+
* @cssprop --pf-v5-c-hint--BorderColor - Border color of the hint
33+
* @cssprop --pf-v5-c-hint--BorderWidth - Border width of the hint
34+
* @cssprop --pf-v5-c-hint--BoxShadow - Box shadow of the hint container
35+
* @cssprop --pf-v5-c-hint--Color - Text color of the hint content
36+
* @cssprop --pf-v5-c-hint__title--FontSize - Font size of the title text
37+
* @cssprop --pf-v5-c-hint__body--FontSize - Font size of the body text
38+
* @cssprop --pf-v5-c-hint__footer--child--MarginRight - Right margin of footer child elements
39+
* @cssprop --pf-v5-c-hint__actions--MarginLeft - Left margin of action elements
40+
* @cssprop --pf-v5-c-hint__actions--MarginLeft - Left margin of action elements
41+
* @cssprop --pf-v5-c-hint__actions--MarginLeft - Left margin of action elements
42+
* @cssprop --pf-v5-c-hint__actions--MarginLeft - Left margin of action elements
43+
* @cssprop --pf-v5-c-hint__actions--MarginLeft - Left margin of action elements
44+
* @cssprop --pf-v5-c-hint__actions--MarginLeft - Left margin of action elements
45+
* @cssprop --pf-v5-c-hint__actions--MarginLeft - Left margin of action elements
46+
* @cssprop --ak-v1-c-hint--m-success--BackgroundColor - Background color for "success" variant
47+
* @cssprop --ak-v1-c-hint--m-success--BorderColor - Border color for "success" variant
48+
* @cssprop --ak-v1-c-hint--m-success__title--Color - Title color for "success" variant
49+
* @cssprop --ak-v1-c-hint--m-warning--BackgroundColor - Background color for "warning" variant
50+
* @cssprop --ak-v1-c-hint--m-warning--BorderColor - Border color for "warning" variant
51+
* @cssprop --ak-v1-c-hint--m-warning__title--Color - Title color for "warning" variant
52+
* @cssprop --ak-v1-c-hint--m-danger--BackgroundColor - Background color for "danger" variant
53+
* @cssprop --ak-v1-c-hint--m-danger--BorderColor - Border color for "danger" variant
54+
* @cssprop --ak-v1-c-hint--m-danger__title--Color - Title color for "danger" variant
55+
* @cssprop
56+
*/
57+
export class Hint extends AkLitElement {
58+
static override readonly styles = [styles];
59+
60+
public override connectedCallback() {
61+
super.connectedCallback();
62+
if (!this.hasAttribute("role")) {
63+
this.setAttribute("role", "note");
64+
}
65+
}
66+
67+
public override render() {
68+
const [hasTitle, hasBody, hasFooter] = ["title", null, "footer"].map((item) =>
69+
this.hasSlotted(item),
70+
);
71+
72+
return html`
73+
<div part="hint">
74+
${hasTitle ? html`<div part="title"><slot name="title"></slot></div>` : nothing}
75+
${hasBody ? html`<div part="body"><slot></slot></div>` : nothing}
76+
${hasFooter ? html`<div part="footer"><slot name="footer"></slot></div>` : nothing}
77+
</div>
78+
`;
79+
}
80+
}

src/ak-hint/ak-hint.css

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
:host {
2+
--hint--GridRowGap: var(--pf-v5-c-hint--GridRowGap, 1rem);
3+
--hint--PaddingTop: var(--pf-v5-c-hint--PaddingTop, 1.5rem);
4+
--hint--PaddingRight: var(--pf-v5-c-hint--PaddingRight, 1.5rem);
5+
--hint--PaddingBottom: var(--pf-v5-c-hint--PaddingBottom, 1.5rem);
6+
--hint--PaddingLeft: var(--pf-v5-c-hint--PaddingLeft, 1.5rem);
7+
--hint--BackgroundColor: var(--pf-v5-c-hint--BackgroundColor, #e7f1fa);
8+
--hint--BorderColor: var(--pf-v5-c-hint--BorderColor, #bee1f4);
9+
--hint--BorderWidth: var(--pf-v5-c-hint--BorderWidth, 1px);
10+
--hint--BoxShadow: var(
11+
--pf-v5-c-hint--BoxShadow,
12+
0 0.0625rem 0.125rem 0 rgb(3 3 3 / 12%),
13+
0 0 0.125rem 0 rgb(3 3 3 / 6%)
14+
);
15+
--hint--Color: var(--pf-v5-c-hint--Color, #151515);
16+
--hint__title--Color: var(--pf-v5-c-hint--Color, #151515);
17+
--hint__title--FontSize: var(--pf-v5-c-hint__title--FontSize, 1.125rem);
18+
--hint__body--FontSize: var(--pf-v5-c-hint__body--FontSize, 1rem);
19+
--hint__footer--child--MarginRight: var(--pf-v5-c-hint__footer--child--MarginRight, 1rem);
20+
--hint__actions--MarginLeft: var(--pf-v5-c-hint__actions--MarginLeft, 3rem);
21+
--hint__actions--c-dropdown--MarginTop: var(
22+
--pf-v5-c-hint__actions--c-dropdown--MarginTop,
23+
calc(0.375rem * -1)
24+
);
25+
--hint--m-success--BackgroundColor: var(--ak-v1-c-hint--m-success--BackgroundColor, #f3faf2);
26+
--hint--m-success--BorderColor: var(--ak-v1-c-hint--m-success--BorderColor, #3e8635);
27+
--hint--m-success__title--Color: var(--ak-v1-c-hint--m-success__title--Color, #3e8635);
28+
--hint--m-warning--BackgroundColor: var(--ak-v1-c-hint--m-warning--BackgroundColor, #fdf7e7);
29+
--hint--m-warning--BorderColor: var(--ak-v1-c-hint--m-warning--BorderColor, #f4c145);
30+
--hint--m-warning__title--Color: var(--ak-v1-c-hint--m-warning__title--Color, #795600);
31+
--hint--m-danger--BackgroundColor: var(--ak-v1-c-hint--m-danger--BackgroundColor, #faeae8);
32+
--hint--m-danger--BorderColor: var(--ak-v1-c-hint--m-danger--BorderColor, #c9190b);
33+
--hint--m-danger__title--Color: var(--ak-v1-c-hint--m-danger__title--Color, #470000);
34+
}
35+
36+
:host(:not([hidden])) {
37+
display: block;
38+
}
39+
40+
[part="hint"] {
41+
display: grid;
42+
grid-template-columns: 1fr auto;
43+
row-gap: var(--hint--GridRowGap);
44+
padding-block-start: var(--hint--PaddingTop);
45+
padding-block-end: var(--hint--PaddingBottom);
46+
padding-inline-start: var(--hint--PaddingLeft);
47+
padding-inline-end: var(--hint--PaddingRight);
48+
color: var(--hint--Color);
49+
background-color: var(--hint--BackgroundColor);
50+
border: var(--hint--BorderWidth) solid var(--hint--BorderColor);
51+
box-shadow: var(--hint--BoxShadow);
52+
}
53+
54+
:host([variant="success"]) {
55+
--hint--BackgroundColor: var(--hint--m-success--BackgroundColor);
56+
--hint--BorderColor: var(--hint--m-success--BorderColor);
57+
--hint__title--Color: var(--hint--m-success__title--Color);
58+
}
59+
60+
:host([variant="warning"]) {
61+
--hint--BackgroundColor: var(--hint--m-warning--BackgroundColor);
62+
--hint--BorderColor: var(--hint--m-warning--BorderColor);
63+
--hint__title--Color: var(--hint--m-warning__title--Color);
64+
}
65+
66+
:host([variant="danger"]) {
67+
--hint--BackgroundColor: var(--hint--m-danger--BackgroundColor);
68+
--hint--BorderColor: var(--hint--m-danger--BorderColor);
69+
--hint__title--Color: var(--hint--m-danger__title--Color);
70+
}
71+
72+
[part="hint"] > [part="title"] ::slotted(*) {
73+
font-size: var(--hint__title--FontSize);
74+
color: var(--hint__title--Color);
75+
}
76+
77+
[part="hint"] > [part="body"] ::slotted(*) {
78+
font-size: var(--hint__body--FontSize);
79+
}
80+
81+
[part="hint"] > [part="footer"] ::slotted(*) {
82+
font-size: var(--hint__footer--FontSize);
83+
}
84+
85+
[part="title"],
86+
[part="body"],
87+
[part="footer"] {
88+
grid-column: 1/-1;
89+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import: hint.css
2+
base: .pf-v5-c-hint
3+
host:
4+
'[part="hint"]':
5+
$from: $base
6+
$include: display, grid-template-columns, grid-row-gap, color, background-color, border, box-shadow, padding-block-start, padding-block-end, padding-inline-start, padding-inline-end
7+
8+
'[part="title"] ::slotted(*)':
9+
font-size: var(--pf-v5-c-hint__title--FontSize) !important;
10+
'[part="body"] ::slotted(*)':
11+
font-size: var(--pf-v5-c-hint__body--FontSize) !important;
12+
'[name="footer"] ::slotted(*)':
13+
font-size: var(--pf-v5-c-hint__footer--FontSize) !important;
14+
'[part="title"], [part="body"], [part="footer"]':
15+
$from: __footer

src/ak-hint/ak-hint.root.css

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
:root {
2+
--pf-v5-c-hint--GridRowGap: var(--pf-v5-global--spacer--md);
3+
--pf-v5-c-hint--PaddingTop: var(--pf-v5-global--spacer--lg);
4+
--pf-v5-c-hint--PaddingRight: var(--pf-v5-global--spacer--lg);
5+
--pf-v5-c-hint--PaddingBottom: var(--pf-v5-global--spacer--lg);
6+
--pf-v5-c-hint--PaddingLeft: var(--pf-v5-global--spacer--lg);
7+
--pf-v5-c-hint--BackgroundColor: var(--pf-v5-global--palette--blue-50);
8+
--pf-v5-c-hint--BorderColor: var(--pf-v5-global--palette--blue-100);
9+
--pf-v5-c-hint--BorderWidth: var(--pf-v5-global--BorderWidth--sm);
10+
--pf-v5-c-hint--BoxShadow: var(--pf-v5-global--BoxShadow--sm);
11+
--pf-v5-c-hint--Color: var(--pf-v5-global--Color--100);
12+
--pf-v5-c-hint__title--FontSize: var(--pf-v5-global--FontSize--lg);
13+
--pf-v5-c-hint__body--FontSize: var(--pf-v5-global--FontSize--md);
14+
--pf-v5-c-hint__footer--child--MarginRight: var(--pf-v5-global--spacer--md);
15+
16+
/* TODO: Incorporate the "actions" block. */
17+
--pf-v5-c-hint__actions--MarginLeft: var(--pf-v5-global--spacer--2xl);
18+
--pf-v5-c-hint__actions--c-dropdown--MarginTop: calc(
19+
var(--pf-v5-global--spacer--form-element) * -1
20+
);
21+
--ak-v1-c-hint__title--Color: var(--pf-v5-global--Color--100);
22+
--ak-v1-c-hint--m-success--BackgroundColor: var(--pf-v5-global--palette--green-50);
23+
--ak-v1-c-hint--m-success--BorderColor: var(--pf-v5-global--success-color--100);
24+
--ak-v1-c-hint--m-success__title--Color: var(--pf-v5-global--success-color--100);
25+
--ak-v1-c-hint--m-warning--BackgroundColor: var(--pf-v5-global--palette--gold-50);
26+
--ak-v1-c-hint--m-warning--BorderColor: var(--pf-v5-global--warning-color--100);
27+
--ak-v1-c-hint--m-warning__title--Color: var(--pf-v5-global--warning-color--200);
28+
--ak-v1-c-hint--m-danger--BackgroundColor: var(--pf-v5-global--palette--red-50);
29+
--ak-v1-c-hint--m-danger--BorderColor: var(--pf-v5-global--danger-color--100);
30+
--ak-v1-c-hint--m-danger__title--Color: var(--pf-v5-global--danger-color--300);
31+
}
32+
33+
.pf-v5-theme-dark,
34+
html[theme="dark"],
35+
html[data-theme="dark"] {
36+
--pf-v5-c-hint--BackgroundColor: var(--pf-v5-global--BackgroundColor--400);
37+
--pf-v5-c-hint--BorderColor: var(--pf-v5-global--BorderColor--300);
38+
}

0 commit comments

Comments
 (0)