-
Notifications
You must be signed in to change notification settings - Fork 77
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(autocomplete): add autocomplete component #10562
Changes from 70 commits
e91067a
f775c65
f9281c3
26ef117
895fb3d
551a4ef
1647737
40ff5a4
74e8475
50bd853
5003bd5
08ddfc6
4b63467
d576694
83b6e04
eaff04d
d134939
ea844e0
023f40a
ef0e707
f5a8775
b287e24
c3ec799
183d4da
ae99b87
b4d4f74
a4f2016
576ec2b
801610f
2edd54f
213530a
36d9abc
3791285
52a99e6
9ac5b36
66c3ec1
a29a378
323bcd9
6415af0
5010488
65c6ef7
1348ea4
e8df8e1
b7dbb1a
c854608
cd09b73
4c65bfa
0f7fbc1
43276a5
0f6d455
8ae99c0
aa834ba
5092329
5991b82
9889c3c
120e7e6
b0a9fbe
eb48083
5bfa535
81b17e0
d40410e
b24c28d
dc4b7e2
5b6abed
33118b3
1882df7
a8a4d9e
e3997d1
90296fa
4178284
35bbe5a
a3921d4
fbb5ccb
caf2f16
1164b1e
4614b26
4e384e5
f3d1892
a18e247
3432c7f
c676592
c519582
100dd99
eb8facb
13b669f
8d7f297
72dba5c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import { describe } from "vitest"; | ||
import { defaults, hidden, renders, themed } from "../../tests/commonTests"; | ||
import { CSS } from "./resources"; | ||
|
||
describe("calcite-autocomplete-item-group", () => { | ||
describe("defaults", () => { | ||
defaults("calcite-autocomplete-item-group", [ | ||
{ propertyName: "disableSpacing", defaultValue: false }, | ||
{ propertyName: "heading", defaultValue: undefined }, | ||
{ propertyName: "label", defaultValue: undefined }, | ||
{ propertyName: "scale", defaultValue: "m" }, | ||
]); | ||
}); | ||
|
||
describe("renders", () => { | ||
renders("calcite-autocomplete-item-group", { display: "flex" }); | ||
}); | ||
|
||
describe("honors hidden attribute", () => { | ||
hidden("calcite-autocomplete-item-group"); | ||
}); | ||
|
||
describe("theme", () => { | ||
themed("calcite-autocomplete-item-group", { | ||
"--calcite-autocomplete-background-color": { | ||
shadowSelector: `.${CSS.container}`, | ||
targetProp: "backgroundColor", | ||
}, | ||
"--calcite-autocomplete-border-color": { | ||
shadowSelector: `.${CSS.heading}`, | ||
targetProp: "borderBlockEndColor", | ||
}, | ||
"--calcite-autocomplete-text-color": { | ||
shadowSelector: `.${CSS.heading}`, | ||
targetProp: "color", | ||
}, | ||
}); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
/** | ||
* CSS Custom Properties | ||
* | ||
* These properties can be overridden using the component's tag as selector. | ||
* | ||
* @prop --calcite-autocomplete-background-color: Specifies the background color of the component. | ||
* @prop --calcite-autocomplete-border-color: Specifies the border color of the component. | ||
* @prop --calcite-autocomplete-text-color: Specifies the text color of the component. | ||
*/ | ||
|
||
.scale--s { | ||
@apply text-n2h; | ||
--calcite-internal-autocomplete-item-group-spacing-unit-l: theme("spacing.2"); | ||
--calcite-internal-autocomplete-item-group-spacing-unit-s: theme("spacing.2"); | ||
} | ||
|
||
.scale--m { | ||
@apply text-n1h; | ||
--calcite-internal-autocomplete-item-group-spacing-unit-l: theme("spacing.3"); | ||
--calcite-internal-autocomplete-item-group-spacing-unit-s: theme("spacing.3"); | ||
} | ||
|
||
.scale--l { | ||
@apply text-0h; | ||
--calcite-internal-autocomplete-item-group-spacing-unit-l: theme("spacing.4"); | ||
--calcite-internal-autocomplete-item-group-spacing-unit-s: theme("spacing.4"); | ||
} | ||
|
||
:host { | ||
@apply m-0 | ||
flex | ||
flex-col; | ||
} | ||
|
||
.container { | ||
@apply flex | ||
flex-col; | ||
background-color: var(--calcite-autocomplete-background-color, var(--calcite-color-foreground-1)); | ||
padding-block-start: var(--calcite-internal-autocomplete-item-group-spacing-unit-l); | ||
} | ||
|
||
.container--no-spacing { | ||
padding-block-start: 0; | ||
} | ||
|
||
.heading { | ||
border: 0 solid; | ||
@apply box-border | ||
w-full | ||
min-w-0 | ||
max-w-full | ||
word-break | ||
border-b | ||
font-bold; | ||
color: var(--calcite-autocomplete-text-color, var(--calcite-color-text-2)); | ||
border-block-end-color: var(--calcite-autocomplete-border-color, var(--calcite-color-border-3)); | ||
padding-block: var(--calcite-internal-autocomplete-item-group-spacing-unit-l); | ||
padding-inline: var(--calcite-internal-autocomplete-item-group-spacing-unit-s); | ||
} | ||
|
||
@include base-component(); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import { LitElement, property, h, JsxNode } from "@arcgis/lumina"; | ||
import { Scale } from "../interfaces"; | ||
import { CSS } from "./resources"; | ||
import { styles } from "./autocomplete-item-group.scss"; | ||
|
||
declare global { | ||
interface DeclareElements { | ||
"calcite-autocomplete-item-group": AutocompleteItemGroup; | ||
} | ||
} | ||
|
||
/** @slot - A slot for adding `calcite-autocomplete-item`s. */ | ||
export class AutocompleteItemGroup extends LitElement { | ||
// #region Static Members | ||
|
||
static override styles = styles; | ||
|
||
// #endregion | ||
|
||
// #region Private Properties | ||
|
||
// #endregion | ||
|
||
// #region Public Properties | ||
|
||
/** | ||
* When `true`, signifies that the group should not have extra spacing. Used for styling. | ||
* | ||
* @private | ||
*/ | ||
@property() disableSpacing = false; | ||
|
||
/** The component's text. */ | ||
@property() heading: string; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this be marked There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @geospatialem what do you think? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good eye by @anveshmekala! Agree since the |
||
|
||
/** The component's label. */ | ||
@property() label: any; | ||
|
||
/** | ||
* Specifies the size of the component inherited from the `calcite-autocomplete`, defaults to `m`. | ||
* | ||
* @private | ||
*/ | ||
@property() scale: Scale = "m"; | ||
|
||
// #endregion | ||
|
||
// #region Lifecycle | ||
|
||
// #endregion | ||
|
||
// #region Rendering | ||
|
||
override render(): JsxNode { | ||
const { scale } = this; | ||
return ( | ||
<div | ||
aria-label={this.label ?? this.heading} | ||
class={{ | ||
[CSS.container]: true, | ||
[CSS.containerNoSpacing]: this.disableSpacing, | ||
[`scale--${scale}`]: true, | ||
}} | ||
role="group" | ||
> | ||
<div class={CSS.heading} role="presentation"> | ||
{this.heading} | ||
</div> | ||
<slot /> | ||
</div> | ||
); | ||
} | ||
|
||
// #endregion | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export const CSS = { | ||
container: "container", | ||
containerNoSpacing: "container--no-spacing", | ||
heading: "heading", | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import { describe } from "vitest"; | ||
import { defaults, disabled, hidden, reflects, renders, slots, themed } from "../../tests/commonTests"; | ||
import { CSS, SLOTS } from "./resources"; | ||
|
||
describe("calcite-autocomplete-item", () => { | ||
describe("defaults", () => { | ||
defaults("calcite-autocomplete-item", [ | ||
{ propertyName: "active", defaultValue: false }, | ||
{ propertyName: "description", defaultValue: undefined }, | ||
{ propertyName: "disabled", defaultValue: false }, | ||
{ propertyName: "heading", defaultValue: undefined }, | ||
{ propertyName: "iconEnd", defaultValue: undefined }, | ||
{ propertyName: "iconFlipRtl", defaultValue: undefined }, | ||
{ propertyName: "iconStart", defaultValue: undefined }, | ||
{ propertyName: "label", defaultValue: undefined }, | ||
{ propertyName: "scale", defaultValue: "m" }, | ||
{ propertyName: "value", defaultValue: undefined }, | ||
]); | ||
}); | ||
|
||
describe("reflects", () => { | ||
reflects("calcite-autocomplete-item", [ | ||
{ propertyName: "disabled", value: true }, | ||
{ propertyName: "iconEnd", value: "banana" }, | ||
{ propertyName: "iconFlipRtl", value: "end" }, | ||
{ propertyName: "iconStart", value: "banana" }, | ||
]); | ||
}); | ||
|
||
describe("renders", () => { | ||
renders("calcite-autocomplete-item", { display: "flex" }); | ||
}); | ||
|
||
describe("honors hidden attribute", () => { | ||
hidden("calcite-autocomplete-item"); | ||
}); | ||
|
||
describe("slots", () => { | ||
slots("calcite-autocomplete-item", SLOTS); | ||
}); | ||
|
||
describe("disabled", () => { | ||
disabled("calcite-autocomplete-item", { focusTarget: "none" }); | ||
}); | ||
|
||
describe("slots", () => { | ||
slots("calcite-autocomplete-item", SLOTS); | ||
}); | ||
|
||
describe("theme", () => { | ||
themed("calcite-autocomplete-item", { | ||
"--calcite-autocomplete-background-color": { | ||
shadowSelector: `.${CSS.container}`, | ||
targetProp: "backgroundColor", | ||
}, | ||
"--calcite-autocomplete-background-color-hover": { | ||
shadowSelector: `.${CSS.container}`, | ||
state: "hover", | ||
targetProp: "backgroundColor", | ||
}, | ||
"--calcite-autocomplete-description-text-color": { | ||
shadowSelector: `.${CSS.description}`, | ||
targetProp: "color", | ||
}, | ||
"--calcite-autocomplete-heading-text-color": { | ||
shadowSelector: `.${CSS.heading}`, | ||
targetProp: "color", | ||
}, | ||
"--calcite-autocomplete-text-color": { | ||
shadowSelector: `.${CSS.container}`, | ||
targetProp: "color", | ||
}, | ||
}); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
/** | ||
* CSS Custom Properties | ||
* | ||
* These properties can be overridden using the component's tag as selector. | ||
* | ||
* @prop --calcite-autocomplete-background-color: Specifies the background color of the component. | ||
* @prop --calcite-autocomplete-background-color-hover: Specifies the background color of the component when hovered. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @alisonailea do we really need this var? I thought if a user could use the host to set the hover state bg color a var wasn't necessary? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Like:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @macandcheese do you know? I thought we only needed bg state specific vars when using the host selector wouldn't work? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe what you have above ( If we added separately focusable / clickable areas to an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @alisonailea can you confirm? |
||
* @prop --calcite-autocomplete-description-text-color: Specifies the text color of the component's description. | ||
* @prop --calcite-autocomplete-heading-text-color: Specifies the text color of the component's heading. | ||
* @prop --calcite-autocomplete-text-color: Specifies the text color of the component. | ||
*/ | ||
|
||
.scale--s { | ||
@apply text-n2h; | ||
--calcite-internal-autocomplete-item-spacing-unit-l: theme("spacing.2"); | ||
--calcite-internal-autocomplete-item-spacing-unit-s: theme("spacing.1"); | ||
--calcite-internal-autocomplete-item-description-font-size: var(--calcite-font-size-xs); | ||
} | ||
|
||
.scale--m { | ||
@apply text-n1h; | ||
--calcite-internal-autocomplete-item-spacing-unit-l: theme("spacing.3"); | ||
--calcite-internal-autocomplete-item-spacing-unit-s: theme("spacing[1.5]"); | ||
--calcite-internal-autocomplete-item-description-font-size: var(--calcite-font-size-sm); | ||
} | ||
|
||
.scale--l { | ||
@apply text-0h; | ||
--calcite-internal-autocomplete-item-spacing-unit-l: theme("spacing.4"); | ||
--calcite-internal-autocomplete-item-spacing-unit-s: theme("spacing[2.5]"); | ||
--calcite-internal-autocomplete-item-description-font-size: var(--calcite-font-size); | ||
} | ||
|
||
:host { | ||
@apply flex; | ||
} | ||
|
||
.container { | ||
@apply flex | ||
w-full | ||
min-w-full | ||
cursor-pointer | ||
focus-base | ||
relative | ||
box-border | ||
items-center; | ||
background-color: var(--calcite-autocomplete-background-color, var(--calcite-color-foreground-1)); | ||
color: var(--calcite-autocomplete-text-color, var(--calcite-color-text-3)); | ||
gap: var(--calcite-internal-autocomplete-item-spacing-unit-l); | ||
padding-inline: var(--calcite-internal-autocomplete-item-spacing-unit-l); | ||
padding-block: var(--calcite-internal-autocomplete-item-spacing-unit-s); | ||
@include word-break(); | ||
justify-content: space-around; | ||
} | ||
|
||
.description { | ||
color: var(--calcite-autocomplete-description-text-color); | ||
font-size: var(--calcite-internal-autocomplete-item-description-font-size); | ||
} | ||
|
||
.heading { | ||
color: var(--calcite-autocomplete-heading-text-color, var(--calcite-color-text-1)); | ||
} | ||
|
||
.heading, | ||
.description { | ||
line-height: var(--calcite-font-line-height-relative-snug); | ||
} | ||
|
||
:host(:hover:not([disabled])) .container { | ||
background-color: var(--calcite-autocomplete-background-color-hover, var(--calcite-color-foreground-2)); | ||
|
||
.description { | ||
color: var(--calcite-autocomplete-description-text-color, var(--calcite-color-text-2)); | ||
} | ||
} | ||
|
||
.container--active { | ||
@apply focus-inset; | ||
} | ||
|
||
.content-center { | ||
display: flex; | ||
flex-direction: column; | ||
flex-grow: 1; | ||
padding-block: 0; | ||
} | ||
|
||
@include base-component(); | ||
@include disabled(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick : can we use one variable here
--calcite-internal-autocomplete-item-group-spacing-unit
. Applies to all scales.