Skip to content

Commit 8fdb75b

Browse files
Merge branch 'main' into element/ak-spinner
* main: element/ak-timestamp: consistency pass and final check element/ak-divider: consistency check and test update elements: structural issues Documentation update Applies the new vitest suite to ak-timestamp. element: ak-timeout And divider is now themable and dark-mode capable. Updating for release. Fixed some lint. Lint and prettier pass. Found a few disconnects, fixed them. Adding the timestamp component. Remove custom registration, run prettier, remove old CSS. Ported from foundation, and heavily revised. An analysis of the CSS revealed it was far more complicated than it needed to be; using the Patternfly trick of communicating embedded state through scoped variables names turned out to be much more coherent.
2 parents 9e6a81c + e96df32 commit 8fdb75b

29 files changed

+2370
-56
lines changed

docs/component-files.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ The following files will be found in almost all components:
3636

3737
The following files can be found with most components:
3838

39-
- `ak-component.test.ts`: A WebdriverIO test file. Not always present; WebdriverIO, the shadowDOM,
40-
and events like mouse-in/mouse-out or timing-based components should have strong storybook demos
41-
instead so developers can affirm that a component behaves as expected.
39+
- `ak-component.test.ts`: A Vitest-and-Playwright test file. Not always present; Playwright, the
40+
shadowDOM, and events like mouse-in/mouse-out or timing-based components should have strong
41+
storybook demos instead so developers can affirm that a component behaves as expected.
4242
- `ak-component.wcc.yaml`: A WCCSS file. These files document _what_ we did to convert Patternfly-5
4343
to a shadowDOM-friendly format. The WCCSS program in the `./tools-src` folder automatically:
4444
- splits a component's React-oriented CSS into a file defining component-namespaced CSS custom

src/ak-brand/ak-brand.component.ts

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,6 @@ import { html, LitElement } from "lit";
44
import { property } from "lit/decorators.js";
55
import { ifDefined } from "lit/directives/if-defined.js";
66

7-
export interface IBrand {
8-
src?: string;
9-
alt?: string;
10-
}
11-
127
/**
138
* @summary A **brand** is an image used to identify an organization, corporation or project.
149
*
@@ -27,15 +22,15 @@ export interface IBrand {
2722
* @cssprop --ak-v1-c-brand--Height-on-xl - Height on extra large screens (≥1200px)
2823
* @cssprop --ak-v1-c-brand--Height-on-2xl - Height on 2x large screens (≥1450px)
2924
*/
30-
export class Brand extends LitElement implements IBrand {
25+
export class Brand extends LitElement {
3126
static readonly styles = [styles];
3227

3328
/** @attr {string} src - The URL for the image source */
34-
@property({ type: String, reflect: true })
29+
@property({ type: String })
3530
src?: string;
3631

3732
/** @attr {string} alt - The alt text for the image (for accessibility) */
38-
@property({ type: String, reflect: true })
33+
@property({ type: String })
3934
alt?: string;
4035

4136
render() {

src/ak-button/ak-button.component.ts

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export type ButtonSeverity = (typeof buttonSeverity)[number];
2929
/**
3030
* Optional button sizes
3131
*/
32-
export const buttonSize = ["sm", "lg"] as const;
32+
export const buttonSize = ["sm", "md", "lg"] as const;
3333
export type ButtonSize = (typeof buttonSize)[number];
3434

3535
/**
@@ -38,18 +38,6 @@ export type ButtonSize = (typeof buttonSize)[number];
3838
export const buttonType = ["button", "submit", "reset"] as const;
3939
export type ButtonType = (typeof buttonType)[number];
4040

41-
export interface IButton {
42-
download?: string;
43-
href?: string;
44-
label?: string;
45-
name?: string;
46-
rel?: string;
47-
target?: string;
48-
type?: ButtonType;
49-
value?: string;
50-
variant?: ButtonVariant;
51-
}
52-
5341
/**
5442
* @element ak-button
5543
*
@@ -67,8 +55,9 @@ export interface IButton {
6755
* - "danger": Red styling for destructive actions
6856
* - "warning": Yellow styling for cautionary actions
6957
* @attr {ButtonSize} size - Button size: "sm", "lg"
70-
* - "small": Smaller than default. Used for compact settings.
71-
* - "large": Larger than default. Used for CTAs.
58+
* - "sm": Smaller than default. Used for compact settings.
59+
* - "md": Medium (the default)
60+
* - "lg": Larger than default. Used for CTAs.
7261
* @attr {string} name - Name attribute for the button
7362
* @attr {string} value - Value attribute when button is part of a form
7463
* @attr {string} label - Aria-accessible label for the button
@@ -115,11 +104,14 @@ export interface IButton {
115104
* @cssprop --pf-v5-c-button--m-warning--BackgroundColor - Warning severity background color
116105
* @cssprop --pf-v5-c-button--m-warning--Color - Warning severity text color
117106
*/
118-
export class Button extends LitElement implements IButton {
107+
export class Button extends LitElement {
119108
static readonly styles = [styles];
120109

121110
static readonly formAssociated = true;
122111

112+
// While it's unlikely that client code will modify these by manipulating `type` and `variant`
113+
// fields directly, it's still possible. Their presence triggers corresponding CSS effects, so
114+
// they must be monitored and reflected.
123115
@property({ reflect: true })
124116
public type?: ButtonType = "button";
125117

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { type DividerOrientation, type DividerVariant } from "./ak-divider.component.js";
2+
3+
import { html, TemplateResult } from "lit";
4+
import { ifDefined } from "lit/directives/if-defined.js";
5+
6+
export type DividerProps = {
7+
variant?: DividerVariant;
8+
orientation?: DividerOrientation;
9+
content?: string | TemplateResult;
10+
};
11+
12+
/**
13+
* @summary Helper function to create a Divider component programmatically
14+
*
15+
* @returns {TemplateResult} A Lit template result containing the configured ak-divider element
16+
*
17+
* @see {@link Divider} - The underlying web component
18+
*/
19+
export function akDivider(options: DividerProps = {}) {
20+
const { variant, orientation, content } = options;
21+
22+
// Handle string content by wrapping in a span
23+
const message = typeof content === "string" ? html`<span>${content.trim()}</span>` : content;
24+
25+
return html`
26+
<ak-divider variant=${ifDefined(variant)} orientation=${ifDefined(orientation)}
27+
>${message}</ak-divider
28+
>
29+
`;
30+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { AkLitElement } from "../component-base.js";
2+
import styles from "./ak-divider.css";
3+
4+
import { html } from "lit";
5+
6+
// These are documented here because they are used by the builder as type constraints. They have
7+
// only visual consequences, so there's no need for them in the component's codebase.
8+
9+
export const dividerVariant = ["default", "strong", "subtle"] as const;
10+
export type DividerVariant = (typeof dividerVariant)[number];
11+
12+
export const dividerOrientation = ["horizontal", "vertical"] as const;
13+
export type DividerOrientation = (typeof dividerOrientation)[number];
14+
15+
/**
16+
* @element ak-divider
17+
* @summary A visual divider that creates thematic breaks or separation between content sections
18+
*
19+
* @attr {string} variant - Visual style variant: "default", "strong", "subtle"
20+
* @attr {string} orientation - Layout orientation: "horizontal", "vertical"
21+
*
22+
* @slot - Optional content to display in the middle of the divider line
23+
*
24+
* @csspart divider - The main container element for the divider
25+
* @csspart line - The line elements (before and after content if content exists)
26+
* @csspart line start - The line element before content (when content is present)
27+
* @csspart line end - The line element after content (when content is present)
28+
* @csspart content - The wrapper around the slotted content
29+
*
30+
* @cssprop --pf-v5-c-divider--line-thickness - Width/thickness of the divider line
31+
* @cssprop --pf-v5-c-divider--color - Default color of the divider line
32+
* @cssprop --pf-v5-c-divider--strong-color - Color for the "strong" variant
33+
* @cssprop --pf-v5-c-divider--subtle-color - Color for the "subtle" variant
34+
* @cssprop --pf-v5-c-divider--display - Display type for the host element
35+
* @cssprop --pf-v5-c-divider--flex-direction - Flex direction for the divider container
36+
* @cssprop --pf-v5-c-divider--content-spacing - Spacing between content and lines
37+
* @cssprop --pf-v5-c-divider--height - Height of the divider component
38+
* @cssprop --pf-v5-c-divider--margin - Margin around the divider
39+
* @cssprop --pf-v5-c-divider__line--before--top - Top position of the line pseudo-element
40+
* @cssprop --pf-v5-c-divider__line--before--left - Left position of the line pseudo-element
41+
* @cssprop --pf-v5-c-divider__line--before--right - Right position of the line pseudo-element
42+
* @cssprop --pf-v5-c-divider__line--before--width - Width of the line pseudo-element
43+
* @cssprop --pf-v5-c-divider__line--before--height - Height of the line pseudo-element
44+
*/
45+
export class Divider extends AkLitElement {
46+
static readonly styles = [styles];
47+
48+
render() {
49+
// The `null` slot means use the unnamed slot; usually only for one-slot components.
50+
const hasContent = this.hasSlotted(null);
51+
return html`<div part="divider">
52+
${hasContent
53+
? html` <span part="line start"></span>
54+
<span part="content"><slot></slot></span>
55+
<span part="line end"></span>`
56+
: html` <span part="line"></span> `}
57+
</div> `;
58+
}
59+
}

src/ak-divider/ak-divider.css

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
:host {
2+
--divider--line-thickness: var(--pf-v5-c-divider--line-thickness, 1px);
3+
--divider--color: var(--pf-v5-c-divider--color, #d2d2d2);
4+
--divider--strong-color: var(--pf-v5-c-divider--strong-color, #8a8d90);
5+
--divider--subtle-color: var(--pf-v5-c-divider--subtle-color, #ededed);
6+
--divider--display: var(--pf-v5-c-divider--display, flex);
7+
--divider--flex-direction: var(--pf-v5-c-divider--flex-direction, row);
8+
--divider--content-spacing: var(--pf-v5-c-divider--content-spacing, 0.35rem);
9+
--divider--height: var(--pf-v5-c-divider--height, auto);
10+
--divider__line--before--top: var(--pf-v5-c-divider__line--before--top, 50%);
11+
--divider__line--before--left: var(--pf-v5-c-divider__line--before--left, 0);
12+
--divider__line--before--width: var(--pf-v5-c-divider__line--before--width, 100%);
13+
--divider--margin: var(--divider--content-spacing) 0;
14+
--divider__line--before--height: var(--divider--line-thickness);
15+
}
16+
17+
:host([orientation="vertical"]) {
18+
--divider--display: inline-flex;
19+
--divider--flex-direction: column;
20+
--divider--content-spacing: 0.2rem;
21+
--divider--height: 100%;
22+
--divider--margin: 0 var(--divider--content-spacing);
23+
--divider__line--before--top: 0;
24+
--divider__line--before--left: 50%;
25+
--divider__line--before--width: var(--divider--line-thickness);
26+
--divider__line--before--height: 100%;
27+
}
28+
29+
:host {
30+
display: var(--divider--display);
31+
height: var(--divider--height);
32+
margin: var(--divider--margin);
33+
}
34+
35+
/* Base divider container styles */
36+
[part="divider"] {
37+
align-items: center;
38+
display: flex;
39+
flex-direction: var(--divider--flex-direction);
40+
width: 100%;
41+
height: var(--divider--height);
42+
}
43+
44+
[part*="line"] {
45+
flex-grow: 1;
46+
position: relative;
47+
}
48+
49+
[part*="line"]::before {
50+
content: "";
51+
position: absolute;
52+
background-color: var(--divider--color);
53+
left: var(--divider__line--before--left);
54+
top: var(--divider__line--before--top);
55+
width: var(--divider__line--before--width);
56+
height: var(--divider__line--before--height);
57+
}
58+
59+
[part="content"] {
60+
display: flex;
61+
align-items: center;
62+
justify-content: center;
63+
padding: 0 var(--divider--content-spacing);
64+
}
65+
66+
::slotted(*) {
67+
color: var(--divider--color);
68+
}
69+
70+
:host([variant="strong"]) {
71+
--divider--color: var(--divider--strong-color);
72+
}
73+
74+
:host([variant="subtle"]) {
75+
--divider--color: var(--divider--subtle-color);
76+
}

src/ak-divider/ak-divider.root.css

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
:root {
2+
--pf-v5-c-divider--line-thickness: 1px;
3+
--pf-v5-c-divider--color: var(--pf-v5-global--BorderColor--100, #d2d2d2);
4+
--pf-v5-c-divider--strong-color: var(--pf-v5-global--BorderColor--light-100, #8a8d90);
5+
--pf-v5-c-divider--subtle-color: var(--pf-v5-global--BorderColor--300, #ededed);
6+
--pf-v5-c-divider--display: flex;
7+
--pf-v5-c-divider--flex-direction: row;
8+
--pf-v5-c-divider--content-spacing: 0.35rem;
9+
--pf-v5-c-divider--height: auto;
10+
--pf-v5-c-divider__line--before--top: 50%;
11+
--pf-v5-c-divider__line--before--left: 0;
12+
--pf-v5-c-divider__line--before--width: 100%;
13+
--pf-v5-c-divider__line--before--height: var(--pf-v5-c-divider--line-thickness);
14+
}
15+
16+
html[theme="dark"] {
17+
--pf-v5-c-divider--color: var(--pf-v5-global--BorderColor--100, #444548);
18+
--pf-v5-c-divider--strong-color: var(--pf-v5-global--BorderColor--light-100, #1b1d21);
19+
--pf-v5-c-divider--subtle-color: var(--pf-v5-global--BorderColor--300, #26292d);
20+
}

0 commit comments

Comments
 (0)